Пример #1
0
static DBusMessage *connect_session(DBusConnection *conn,
                                    DBusMessage *msg, void *user_data)
{
    struct connman_session *session = user_data;

    DBG("session %p", session);

    if (ecall_session) {
        if (ecall_session->ecall && ecall_session != session)
            return __connman_error_failed(msg, EBUSY);

        session->ecall = true;
    }

    if (!session->active) {
        session->active = true;
        set_active_session(session, true);
    }

    session_activate(session);

    __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_SESSION);

    return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
Пример #2
0
int connman_session_config_update(struct connman_session *session)
{
    struct session_info *info = session->info;
    GSList *allowed_bearers;
    int err;

    DBG("session %p", session);

    /*
     * We update all configuration even though only one entry
     * might have changed. We can still optimize this later.
     */

    if (session->id_type != session->policy_config->id_type) {
        cleanup_firewall_session(session);
        err = init_firewall_session(session);
        if (err < 0) {
            connman_session_destroy(session);
            return err;
        }

        session->id_type = session->policy_config->id_type;
    }

    apply_policy_on_bearers(
        session->policy_config->allowed_bearers,
        session->user_allowed_bearers,
        &allowed_bearers);

    if (session->active)
        set_active_session(session, false);

    session->active = false;
    session_deactivate(session);

    g_slist_free(info->config.allowed_bearers);
    info->config.allowed_bearers = allowed_bearers;

    session_activate(session);

    info->config.type = apply_policy_on_type(
                            session->policy_config->type,
                            info->config.type);

    info->config.roaming_policy = session->policy_config->roaming_policy;

    info->config.ecall = session->policy_config->ecall;
    if (info->config.ecall)
        ecall_session = session;

    info->config.priority = session->policy_config->priority;

    session_notify(session);

    return 0;
}
Пример #3
0
static void handle_service_state_offline(struct connman_service *service,
					struct connman_service_info *info)
{
	GSList *list;

	for (list = info->sessions; list; list = list->next) {
		struct connman_session *session = list->data;

		if (session->service != service) {
			connman_warn("session %p should have session %p assigned",
					session, service);
			continue;
		}

		DBG("session %p remove service %p", session, service);

		session->service = NULL;
		update_session_state(session);
		session_activate(session);
	}
}
Пример #4
0
static int session_policy_config_cb(struct connman_session *session,
                                    struct connman_session_config *config,
                                    void *user_data, int err)
{
    struct creation_data *creation_data = user_data;
    struct session_info *info, *info_last;
    DBusMessage *reply;

    DBG("session %p config %p", session, config);

    if (err < 0)
        goto err;

    session->policy_config = config;

    session->mark = session_mark++;
    session->index = -1;

    err = init_firewall_session(session);
    if (err < 0)
        goto err;

    err = init_routing_table(session);
    if (err < 0)
        goto err;

    info = session->info;
    info_last = session->info_last;

    if (session->policy_config->ecall)
        ecall_session = session;

    info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
    info->config.type = apply_policy_on_type(
                            session->policy_config->type,
                            creation_data->type);
    info->config.priority = session->policy_config->priority;
    info->config.roaming_policy = session->policy_config->roaming_policy;

    session->user_allowed_bearers = creation_data->allowed_bearers;
    creation_data->allowed_bearers = NULL;

    apply_policy_on_bearers(
        session->policy_config->allowed_bearers,
        session->user_allowed_bearers,
        &info->config.allowed_bearers);

    g_hash_table_replace(session_hash, session->session_path, session);

    DBG("add %s", session->session_path);

    if (!g_dbus_register_interface(connection, session->session_path,
                                   CONNMAN_SESSION_INTERFACE,
                                   session_methods, NULL, NULL,
                                   session, NULL)) {
        connman_error("Failed to register %s", session->session_path);
        g_hash_table_remove(session_hash, session->session_path);
        err = -EINVAL;
        goto err;
    }

    reply = g_dbus_create_reply(creation_data->pending,
                                DBUS_TYPE_OBJECT_PATH, &session->session_path,
                                DBUS_TYPE_INVALID);
    g_dbus_send_message(connection, reply);
    creation_data->pending = NULL;

    info_last->state = info->state;
    info_last->config.priority = info->config.priority;
    info_last->config.roaming_policy = info->config.roaming_policy;
    info_last->config.allowed_bearers = info->config.allowed_bearers;

    session->append_all = true;

    cleanup_creation_data(creation_data);

    session_activate(session);

    return 0;

err:
    reply = __connman_error_failed(creation_data->pending, -err);
    g_dbus_send_message(connection, reply);
    creation_data->pending = NULL;

    cleanup_session(session);
    cleanup_creation_data(creation_data);

    return err;
}
Пример #5
0
static DBusMessage *change_session(DBusConnection *conn,
                                   DBusMessage *msg, void *user_data)
{
    struct connman_session *session = user_data;
    struct session_info *info = session->info;
    DBusMessageIter iter, value;
    const char *name;
    const char *val;
    GSList *allowed_bearers;
    int err;

    DBG("session %p", session);
    if (!dbus_message_iter_init(msg, &iter))
        return __connman_error_invalid_arguments(msg);

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
        return __connman_error_invalid_arguments(msg);

    dbus_message_iter_get_basic(&iter, &name);
    dbus_message_iter_next(&iter);

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
        return __connman_error_invalid_arguments(msg);

    dbus_message_iter_recurse(&iter, &value);

    switch (dbus_message_iter_get_arg_type(&value)) {
    case DBUS_TYPE_ARRAY:
        if (g_str_equal(name, "AllowedBearers")) {
            err = parse_bearers(&value, &allowed_bearers);
            if (err < 0)
                return __connman_error_failed(msg, -err);

            if (session->active)
                set_active_session(session, false);

            session->active = false;
            session_deactivate(session);

            g_slist_free(info->config.allowed_bearers);
            session->user_allowed_bearers = allowed_bearers;

            apply_policy_on_bearers(
                session->policy_config->allowed_bearers,
                session->user_allowed_bearers,
                &info->config.allowed_bearers);

            session_activate(session);
        } else {
            goto err;
        }
        break;
    case DBUS_TYPE_STRING:
        if (g_str_equal(name, "ConnectionType")) {
            dbus_message_iter_get_basic(&value, &val);
            info->config.type = apply_policy_on_type(
                                    session->policy_config->type,
                                    connman_session_parse_connection_type(val));
        } else {
            goto err;
        }
        break;
    default:
        goto err;
    }

    session_notify(session);

    return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);

err:
    return __connman_error_invalid_arguments(msg);
}
static DBusHandlerResult session_message_dispatch(
                Session *s,
                DBusConnection *connection,
                DBusMessage *message) {

        const BusProperty properties[] = {
                { "org.freedesktop.login1.Session", "Id",                 bus_property_append_string,   "s",    s->id                   },
                { "org.freedesktop.login1.Session", "User",               bus_session_append_user,      "(uo)", s                       },
                { "org.freedesktop.login1.Session", "Name",               bus_property_append_string,   "s",    s->user->name           },
                { "org.freedesktop.login1.Session", "Timestamp",          bus_property_append_usec,     "t",    &s->timestamp.realtime  },
                { "org.freedesktop.login1.Session", "TimestampMonotonic", bus_property_append_usec,     "t",    &s->timestamp.monotonic },
                { "org.freedesktop.login1.Session", "ControlGroupPath",   bus_property_append_string,   "s",    s->cgroup_path          },
                { "org.freedesktop.login1.Session", "VTNr",               bus_property_append_uint32,   "u",    &s->vtnr                },
                { "org.freedesktop.login1.Session", "Seat",               bus_session_append_seat,      "(so)", s                       },
                { "org.freedesktop.login1.Session", "TTY",                bus_property_append_string,   "s",    s->tty                  },
                { "org.freedesktop.login1.Session", "Display",            bus_property_append_string,   "s",    s->display              },
                { "org.freedesktop.login1.Session", "Remote",             bus_property_append_bool,     "b",    &s->remote              },
                { "org.freedesktop.login1.Session", "RemoteUser",         bus_property_append_string,   "s",    s->remote_user          },
                { "org.freedesktop.login1.Session", "RemoteHost",         bus_property_append_string,   "s",    s->remote_host          },
                { "org.freedesktop.login1.Session", "Service",            bus_property_append_string,   "s",    s->service              },
                { "org.freedesktop.login1.Session", "Leader",             bus_property_append_pid,      "u",    &s->leader              },
                { "org.freedesktop.login1.Session", "Audit",              bus_property_append_uint32,   "u",    &s->audit_id            },
                { "org.freedesktop.login1.Session", "Type",               bus_session_append_type,      "s",    &s->type                },
                { "org.freedesktop.login1.Session", "Active",             bus_session_append_active,    "b",    s                       },
                { "org.freedesktop.login1.Session", "Controllers",        bus_property_append_strv,     "as",   s->controllers          },
                { "org.freedesktop.login1.Session", "ResetControllers",   bus_property_append_strv,     "as",   s->reset_controllers    },
                { "org.freedesktop.login1.Session", "KillProcesses",      bus_property_append_bool,     "b",    &s->kill_processes      },
                { "org.freedesktop.login1.Session", "IdleHint",           bus_session_append_idle_hint, "b",    s                       },
                { "org.freedesktop.login1.Session", "IdleSinceHint",          bus_session_append_idle_hint_since, "t", s                },
                { "org.freedesktop.login1.Session", "IdleSinceHintMonotonic", bus_session_append_idle_hint_since, "t", s                },
                { NULL, NULL, NULL, NULL, NULL }
        };

        DBusError error;
        DBusMessage *reply = NULL;
        int r;

        assert(s);
        assert(connection);
        assert(message);

        dbus_error_init(&error);

        if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Terminate")) {

                r = session_stop(s);
                if (r < 0)
                        return bus_send_error_reply(connection, message, NULL, r);

                reply = dbus_message_new_method_return(message);
                if (!reply)
                        goto oom;

        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Activate")) {

                r = session_activate(s);
                if (r < 0)
                        return bus_send_error_reply(connection, message, NULL, r);

                reply = dbus_message_new_method_return(message);
                if (!reply)
                        goto oom;

        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") ||
                   dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) {

                if (session_send_signal(s, streq(dbus_message_get_member(message), "Lock")) < 0)
                        goto oom;

                reply = dbus_message_new_method_return(message);
                if (!reply)
                        goto oom;

        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "SetIdleHint")) {
                dbus_bool_t b;
                unsigned long ul;

                if (!dbus_message_get_args(
                                    message,
                                    &error,
                                    DBUS_TYPE_BOOLEAN, &b,
                                    DBUS_TYPE_INVALID))
                        return bus_send_error_reply(connection, message, &error, -EINVAL);

                ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), &error);
                if (ul == (unsigned long) -1)
                        return bus_send_error_reply(connection, message, &error, -EIO);

                if (ul != 0 && ul != s->user->uid)
                        return bus_send_error_reply(connection, message, NULL, -EPERM);

                session_set_idle_hint(s, b);

                reply = dbus_message_new_method_return(message);
                if (!reply)
                        goto oom;

        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Kill")) {
                const char *swho;
                int32_t signo;
                KillWho who;

                if (!dbus_message_get_args(
                                    message,
                                    &error,
                                    DBUS_TYPE_STRING, &swho,
                                    DBUS_TYPE_INT32, &signo,
                                    DBUS_TYPE_INVALID))
                        return bus_send_error_reply(connection, message, &error, -EINVAL);

                if (isempty(swho))
                        who = KILL_ALL;
                else {
                        who = kill_who_from_string(swho);
                        if (who < 0)
                                return bus_send_error_reply(connection, message, &error, -EINVAL);
                }

                if (signo <= 0 || signo >= _NSIG)
                        return bus_send_error_reply(connection, message, &error, -EINVAL);

                r = session_kill(s, who, signo);
                if (r < 0)
                        return bus_send_error_reply(connection, message, NULL, r);

                reply = dbus_message_new_method_return(message);
                if (!reply)
                        goto oom;

        } else
                return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);

        if (reply) {
                if (!dbus_connection_send(connection, reply, NULL))
                        goto oom;

                dbus_message_unref(reply);
        }

        return DBUS_HANDLER_RESULT_HANDLED;

oom:
        if (reply)
                dbus_message_unref(reply);

        dbus_error_free(&error);

        return DBUS_HANDLER_RESULT_NEED_MEMORY;
}