Example #1
0
/**
 * dbus_server_setup_with_g_main:
 * @server: the server
 * @context: the #GMainContext or #NULL for default
 *
 * Sets the watch and timeout functions of a #DBusServer
 * to integrate the server with the GLib main loop.
 * In most cases the context argument should be #NULL.
 *
 * If called twice for the same context, does nothing the second
 * time. If called once with context A and once with context B,
 * context B replaces context A as the context monitoring the
 * connection.
 */
void
dbus_server_setup (DBusServer   *server,
				   GMainContext *context)
{
    ConnectionSetup *old_setup;
    ConnectionSetup *cs;

    do {
        /* FIXME we never free the slot, so its refcount just keeps growing,
         * which is kind of broken.
         */
        dbus_server_allocate_data_slot (&server_slot);
        if (server_slot < 0)
            break;

        if (context == NULL)
            context = g_main_context_default ();

        cs = NULL;

        old_setup = dbus_server_get_data (server, server_slot);
        if (old_setup != NULL) {
            if (old_setup->context == context)
                return; /* nothing to do */

            cs = connection_setup_new_from_old (context, old_setup);

            /* Nuke the old setup */
            dbus_server_set_data (server, server_slot, NULL, NULL);
            old_setup = NULL;
        }

        if (cs == NULL)
            cs = connection_setup_new (context, NULL);

        if (!dbus_server_set_data (server, server_slot, cs,
                                   (DBusFreeFunction)connection_setup_free))
            break;

        if (!dbus_server_set_watch_functions (server,
                                              add_watch,
                                              remove_watch,
                                              watch_toggled,
                                              cs, NULL))
            break;

        if (!dbus_server_set_timeout_functions (server,
                                                add_timeout,
                                                remove_timeout,
                                                timeout_toggled,
                                                cs, NULL))
            break;

        return;
    } while (0);
    
    g_error ("Not enough memory to set up DBusServer for use with GLib");
}
Example #2
0
File: bus.c Project: kobolabs/dbus
static dbus_bool_t
setup_server (BusContext *context,
              DBusServer *server,
              char      **auth_mechanisms,
              DBusError  *error)
{
  BusServerData *bd;

  bd = dbus_new0 (BusServerData, 1);
  if (bd == NULL || !dbus_server_set_data (server,
                                           server_data_slot,
                                           bd, free_server_data))
    {
      dbus_free (bd);
      BUS_SET_OOM (error);
      return FALSE;
    }

  bd->context = context;

  if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  dbus_server_set_new_connection_function (server,
                                           new_connection_callback,
                                           context, NULL);

  if (!dbus_server_set_watch_functions (server,
                                        add_server_watch,
                                        remove_server_watch,
                                        toggle_server_watch,
                                        server,
                                        NULL))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  if (!dbus_server_set_timeout_functions (server,
                                          add_server_timeout,
                                          remove_server_timeout,
                                          NULL,
                                          server, NULL))
    {
      BUS_SET_OOM (error);
      return FALSE;
    }

  return TRUE;
}
void
test_server_shutdown (DBusLoop         *loop,
                      DBusServer       *server)
{
  dbus_server_disconnect (server);

  if (!dbus_server_set_watch_functions (server,
                                        NULL, NULL, NULL,
                                        NULL,
                                        NULL))
    _dbus_assert_not_reached ("setting watch functions to NULL failed");
  
  if (!dbus_server_set_timeout_functions (server,
                                          NULL, NULL, NULL,
                                          NULL,
                                          NULL))
    _dbus_assert_not_reached ("setting timeout functions to NULL failed");  
}
dbus_bool_t
test_server_setup (DBusLoop      *loop,
                   DBusServer    *server)
{
  ServerData *sd;

  sd = serverdata_new (loop, server);
  if (sd == NULL)
    goto nomem;

  if (!dbus_server_set_watch_functions (server,
                                        add_server_watch,
                                        remove_server_watch,
                                        toggle_server_watch,
                                        sd,
                                        serverdata_free))
    {
      goto nomem;
    }

  sd = serverdata_new (loop, server);
  if (sd == NULL)
    goto nomem;

  if (!dbus_server_set_timeout_functions (server,
                                          add_server_timeout,
                                          remove_server_timeout,
                                          NULL,
                                          sd, serverdata_free))
    {
      goto nomem;
    }   
  return TRUE;

 nomem:
  if (sd)
    serverdata_free (sd);
  
  test_server_shutdown (loop, server);
  
  return FALSE;
}
Integrator::Integrator( DBusServer *server, QObject *parent )
  : QObject( parent ), m_server( server )
{
  m_connection = reinterpret_cast<DBusConnection*>( m_server );
  m_timeouts.setAutoDelete( true );

  dbus_server_set_watch_functions( m_server,
                                   dbusAddWatch,
                                   dbusRemoveWatch,
                                   dbusToggleWatch,
                                   this, 0 );
  dbus_server_set_timeout_functions( m_server,
                                     dbusAddTimeout,
                                     dbusRemoveTimeout,
                                     dbusToggleTimeout,
                                     this, 0 );
  dbus_server_set_new_connection_function( m_server,
                                           dbusNewConnection,
                                           this,  0 );
}
Example #6
0
/*
 * dbus_new_server
 * Set up a D-BUS server, integrate with the event loop
 * for handling file descriptor and timed events
 */
int sbus_new_server(TALLOC_CTX *mem_ctx,
                    struct tevent_context *ev,
                    const char *address,
                    uid_t uid, gid_t gid,
                    bool use_symlink,
                    struct sbus_connection **_server,
                    sbus_server_conn_init_fn init_fn,
                    void *init_pvt_data)
{
    struct sbus_connection *server;
    DBusServer *dbus_server;
    DBusError dbus_error;
    dbus_bool_t dbret;
    char *tmp;
    int ret, tmp_ret;
    char *filename;
    char *symlink_filename = NULL;
    const char *socket_address;
    struct stat stat_buf;
    TALLOC_CTX *tmp_ctx;

    *_server = NULL;

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) return ENOMEM;

    socket_address = get_socket_address(tmp_ctx, address, use_symlink);
    if (!socket_address) {
        ret = ENOMEM;
        goto done;
    }

    /* Set up D-BUS server */
    dbus_error_init(&dbus_error);
    dbus_server = dbus_server_listen(socket_address, &dbus_error);
    if (!dbus_server) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "dbus_server_listen failed! (name=%s, message=%s)\n",
                 dbus_error.name, dbus_error.message);
        if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
        ret = EIO;
        goto done;
    }

    filename = strchr(socket_address, '/');
    if (filename == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Unexpected dbus address [%s].\n", socket_address);
        ret = EIO;
        goto done;
    }

    if (use_symlink) {
        symlink_filename = strchr(address, '/');
        if (symlink_filename == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Unexpected dbus address [%s].\n", address);
            ret = EIO;
            goto done;
        }

        ret = create_socket_symlink(filename, symlink_filename);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Could not create symlink [%d]: %s\n",
                      ret, strerror(ret));
            ret = EIO;
            goto done;
        }
    }

    /* Both check_file and chmod can handle both the symlink and
     * the socket */
    ret = check_file(filename,
                     getuid(), getgid(), S_IFSOCK, S_IFMT, &stat_buf, true);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "check_file failed for [%s].\n", filename);
        ret = EIO;
        goto done;
    }

    if ((stat_buf.st_mode & ~S_IFMT) != (S_IRUSR|S_IWUSR)) {
        ret = chmod(filename, (S_IRUSR|S_IWUSR));
        if (ret != EOK) {
            ret = errno;
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "chmod failed for [%s]: [%d][%s].\n", filename, ret,
                                                        sss_strerror(ret));
            ret = EIO;
            goto done;
        }
    }

    if (stat_buf.st_uid != uid || stat_buf.st_gid != gid) {
        ret = chown(filename, uid, gid);
        if (ret != EOK) {
            ret = errno;
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "chown failed for [%s]: [%d][%s].\n", filename, ret,
                                                        sss_strerror(ret));
            ret = EIO;
            goto done;
        }
    }

    tmp = dbus_server_get_address(dbus_server);
    DEBUG(SSSDBG_TRACE_FUNC, "D-BUS Server listening on %s\n", tmp);
    free(tmp);

    server = talloc_zero(tmp_ctx, struct sbus_connection);
    if (!server) {
        ret = ENOMEM;
        goto done;
    }

    server->ev = ev;
    server->type = SBUS_SERVER;
    server->dbus.server = dbus_server;
    server->srv_init_fn = init_fn;
    server->srv_init_data = init_pvt_data;

    talloc_set_destructor((TALLOC_CTX *)server, sbus_server_destructor);

    if (use_symlink) {
        server->symlink = talloc_strdup(server, symlink_filename);
        if (!server->symlink) {
            ret = ENOMEM;
            goto done;
        }
    }

    /* Set up D-BUS new connection handler */
    dbus_server_set_new_connection_function(server->dbus.server,
                                            sbus_server_init_new_connection,
                                            server, NULL);

    /* Set up DBusWatch functions */
    dbret = dbus_server_set_watch_functions(server->dbus.server,
                                            sbus_add_watch,
                                            sbus_remove_watch,
                                            sbus_toggle_watch,
                                            server, NULL);
    if (!dbret) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Error setting up D-BUS server watch functions\n");
        ret = EIO;
        goto done;
    }

    /* Set up DBusTimeout functions */
    dbret = dbus_server_set_timeout_functions(server->dbus.server,
                                              sbus_add_timeout,
                                              sbus_remove_timeout,
                                              sbus_toggle_timeout,
                                              server, NULL);
    if (!dbret) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Error setting up D-BUS server timeout functions\n");
        dbus_server_set_watch_functions(server->dbus.server,
                                        NULL, NULL, NULL, NULL, NULL);
        ret = EIO;
        goto done;
    }

    *_server = talloc_steal(mem_ctx, server);
    ret = EOK;

done:
    if (ret != EOK && symlink_filename) {
        tmp_ret = unlink(symlink_filename);
        /* non-fatal failure */
        if (tmp_ret != EOK) {
            tmp_ret = errno;
            DEBUG(SSSDBG_MINOR_FAILURE,
                  "Failed to remove symbolic link '%s': %d [%s]!\n",
                  symlink_filename, tmp_ret, sss_strerror(tmp_ret));
        }
    }
    talloc_free(tmp_ctx);
    return ret;
}