Пример #1
0
int terminate_machine(
                sd_bus *bus,
                const char *machine_name) {

        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(bus);

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.machine1",
                        "/org/freedesktop/machine1",
                        "org.freedesktop.machine1.Manager",
                        "TerminateMachine",
                        &error,
                        NULL,
                        "s",
                        machine_name);
        if (r < 0)
                log_debug("Failed to terminate machine: %s", bus_error_message(&error, r));

        return 0;
}
Пример #2
0
//------------------------------------------------------------------------
// Takes FRU data, invokes Parser for each fru record area and updates
// Inventory
//------------------------------------------------------------------------
int ipmi_update_inventory(const uint8_t fruid, const uint8_t *fru_data, 
                          fru_area_vec_t & area_vec)
{
    // Now, use this fru dictionary object and connect with FRU Inventory Dbus
    // and update the data for this FRU ID.
    int rc = 0;
    
    // Dictionary object to hold Name:Value pair
    sd_bus_message *fru_dict = NULL;

    // SD Bus error report mechanism.
    sd_bus_error bus_error = SD_BUS_ERROR_NULL;

    // Gets a hook onto either a SYSTEM or SESSION bus
    sd_bus *bus_type = ipmid_get_sd_bus_connection();

    // Req message contains the specifics about which method etc that we want to
    // access on which bus, object
    sd_bus_message *response = NULL;

    // For each FRU area, extract the needed data , get it parsed and update
    // the Inventory.
    for(auto& iter : area_vec)
    {
        uint8_t area_type = (iter).type;

        uint8_t area_data[(iter).len];
        memset(area_data, 0x0, sizeof(area_data));

        // Grab area specific data
        memmove(area_data, (iter).offset, (iter).len);

        // Need this to get respective DBUS objects
        const char *area_name  = NULL;

        if(area_type == IPMI_FRU_AREA_CHASSIS_INFO)
        {
            area_name = "CHASSIS_";
        }
        else if(area_type == IPMI_FRU_AREA_BOARD_INFO)
        {
            area_name = "BOARD_";
        }
        else if(area_type == IPMI_FRU_AREA_PRODUCT_INFO)
        {
            area_name = "PRODUCT_";
        }
        else
        {
            fprintf(stderr, "ERROR: Invalid Area type :[%d]",area_type);
            break;
        }
 
        // What we need is BOARD_1, PRODUCT_1, CHASSIS_1 etc..
        char fru_area_name[16] = {0};
        sprintf(fru_area_name,"%s%d",area_name, fruid);

#ifdef __IPMI_DEBUG__
        printf("Updating Inventory with :[%s]\n",fru_area_name);
#endif
        // Each area needs a clean set.       
        sd_bus_error_free(&bus_error);
        sd_bus_message_unref(response);
        sd_bus_message_unref(fru_dict);
    
        // We want to call a method "getObjectFromId" on System Bus that is
        // made available over  OpenBmc system services.
        rc = sd_bus_call_method(bus_type,                   // On the System Bus
                                bus_name,                   // Service to contact
                                object_name,                // Object path 
                                intf_name,                  // Interface name
                                "getObjectFromId",          // Method to be called
                                &bus_error,                 // object to return error
                                &response,                  // Response message on success
                                "ss",                       // input message (string,byte)
                                "FRU_STR",                  // First argument to getObjectFromId
                                fru_area_name);             // Second Argument

        if(rc < 0)
        {
            fprintf(stderr, "Failed to issue method call: %s\n", bus_error.message);
            break;
        }

        // Method getObjectFromId returns 3 parameters and all are strings, namely
        // bus_name , object_path and interface name for accessing that particular 
        // FRU over Inventory SDBUS manager. 'sss' here mentions that format.
        char *inv_bus_name, *inv_obj_path, *inv_intf_name;
        rc = sd_bus_message_read(response, "(sss)", &inv_bus_name, &inv_obj_path, &inv_intf_name);
        if(rc < 0)
        {
            fprintf(stderr, "Failed to parse response message:[%s]\n", strerror(-rc));
            break;
        }

#ifdef __IPMI_DEBUG__
        printf("fru_area=[%s], inv_bus_name=[%s], inv_obj_path=[%s],inv_intf_name=[%s]\n",
                fru_area_name, inv_bus_name, inv_obj_path, inv_intf_name);
#endif

        // Constructor to allow further initializations and customization.
        rc = sd_bus_message_new_method_call(bus_type,
                                            &fru_dict,
                                            inv_bus_name,
                                            inv_obj_path,
                                            inv_intf_name,
                                            "update");
        if(rc < 0)
        {
            fprintf(stderr,"ERROR: creating a update method call\n");
            break;
        }

        // A Dictionary ({}) having (string, variant)
        rc = sd_bus_message_open_container(fru_dict, 'a', "{sv}");
        if(rc < 0)
        {
            fprintf(stderr,"ERROR:[%d] creating a dict container:\n",errno);
            break;
        }

        // Fill the container with information
        rc = parse_fru_area((iter).type, (void *)area_data, (iter).len, fru_dict);
        if(rc < 0)
        {
            fprintf(stderr,"ERROR parsing FRU records\n");
            break;
        }

        sd_bus_message_close_container(fru_dict);

        // Now, Make the actual call to update the FRU inventory database with the
        // dictionary given by FRU Parser. There is no response message expected for
        // this.
        rc = sd_bus_call(bus_type,            // On the System Bus
                         fru_dict,            // With the Name:value dictionary array
                         0,                   // 
                         &bus_error,          // Object to return error.
                         &response);          // Response message if any.

        if(rc < 0)
        {
            fprintf(stderr, "ERROR:[%s] updating FRU inventory for ID:[0x%X]\n",
                    bus_error.message, fruid);
        }
        else
        {
            printf("SUCCESS: Updated:[%s] successfully\n",fru_area_name);
        }
    } // END walking the vector of areas and updating

    sd_bus_error_free(&bus_error);
    sd_bus_message_unref(response);
    sd_bus_message_unref(fru_dict);
    sd_bus_unref(bus_type);

    return rc;
}
Пример #3
0
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(bus);
        assert(path);

        r = sd_bus_call_method(bus,
                        dest,
                        path,
                        "org.freedesktop.DBus.Properties",
                        "GetAll",
                        &error,
                        &reply,
                        "s", "");
        if (r < 0)
                return r;

        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
        if (r < 0)
                return r;

        while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
                const char *name;
                const char *contents;

                r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
                if (r < 0)
                        return r;

                if (!filter || strv_find(filter, name)) {
                        r = sd_bus_message_peek_type(reply, NULL, &contents);
                        if (r < 0)
                                return r;

                        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
                        if (r < 0)
                                return r;

                        r = bus_print_property(name, reply, all);
                        if (r < 0)
                                return r;
                        if (r == 0) {
                                if (all)
                                        printf("%s=[unprintable]\n", name);
                                /* skip what we didn't read */
                                r = sd_bus_message_skip(reply, contents);
                                if (r < 0)
                                        return r;
                        }

                        r = sd_bus_message_exit_container(reply);
                        if (r < 0)
                                return r;
                } else {
                        r = sd_bus_message_skip(reply, "v");
                        if (r < 0)
                                return r;
                }

                r = sd_bus_message_exit_container(reply);
                if (r < 0)
                        return r;
        }
        if (r < 0)
                return r;

        r = sd_bus_message_exit_container(reply);
        if (r < 0)
                return r;

        return 0;
}
Пример #4
0
static int client(struct context *c) {
        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
        _cleanup_bus_unref_ sd_bus *bus = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        const char *s;
        int r;

        assert_se(sd_bus_new(&bus) >= 0);
        assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
        assert_se(sd_bus_start(bus) >= 0);

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "NoOperation", &error, NULL, NULL);
        assert_se(r >= 0);

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "s", "hallo");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        assert_se(streq(s, "<<<hallo>>>"));

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Doesntexist", &error, &reply, "");
        assert_se(r < 0);
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));

        sd_bus_error_free(&error);

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "as", 1, "hallo");
        assert_se(r < 0);
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS));

        sd_bus_error_free(&error);

        r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        assert_se(streq(s, "<<<hallo>>>"));

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, "s", "test");
        assert_se(r >= 0);

        r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        assert_se(streq(s, "test"));

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticIntegerProperty", &error, "u", 815);
        assert_se(r >= 0);

        assert_se(c->automatic_integer_property == 815);

        r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticStringProperty", &error, "s", "Du Dödel, Du!");
        assert_se(r >= 0);

        assert_se(streq(c->automatic_string_property, "Du Dödel, Du!"));

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        fputs(s, stdout);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/value/xuzz", "org.freedesktop.systemd.ValueTest", "Value", &error, &reply, "s");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        log_info("read %s", s);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        fputs(s, stdout);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        fputs(s, stdout);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
        assert_se(r >= 0);

        r = sd_bus_message_read(reply, "s", &s);
        assert_se(r >= 0);
        fputs(s, stdout);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", "");
        assert_se(r >= 0);

        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", "org.freedesktop.systemd.ValueTest2");
        assert_se(r < 0);
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_INTERFACE));
        sd_bus_error_free(&error);

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, "");
        assert_se(r < 0);
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
        sd_bus_error_free(&error);

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, "");
        assert_se(r >= 0);

        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest", &error, NULL, "");
        assert_se(r >= 0);

        r = sd_bus_process(bus, &reply);
        assert_se(r > 0);

        assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest2", &error, NULL, "");
        assert_se(r >= 0);

        r = sd_bus_process(bus, &reply);
        assert_se(r > 0);

        assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesAdded", &error, NULL, "");
        assert_se(r >= 0);

        r = sd_bus_process(bus, &reply);
        assert_se(r > 0);

        assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesRemoved", &error, NULL, "");
        assert_se(r >= 0);

        r = sd_bus_process(bus, &reply);
        assert_se(r > 0);

        assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectAdded", &error, NULL, "");
        assert_se(r >= 0);

        r = sd_bus_process(bus, &reply);
        assert_se(r > 0);

        assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectRemoved", &error, NULL, "");
        assert_se(r >= 0);

        r = sd_bus_process(bus, &reply);
        assert_se(r > 0);

        assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
        bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);

        sd_bus_message_unref(reply);
        reply = NULL;

        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Exit", &error, NULL, "");
        assert_se(r >= 0);

        sd_bus_flush(bus);

        return 0;
}
Пример #5
0
int register_machine(
                sd_bus *bus,
                const char *machine_name,
                pid_t pid,
                const char *directory,
                sd_id128_t uuid,
                int local_ifindex,
                const char *slice,
                CustomMount *mounts,
                unsigned n_mounts,
                int kill_signal,
                char **properties,
                bool keep_unit,
                const char *service) {

        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(bus);

        if (keep_unit) {
                r = sd_bus_call_method(
                                bus,
                                "org.freedesktop.machine1",
                                "/org/freedesktop/machine1",
                                "org.freedesktop.machine1.Manager",
                                "RegisterMachineWithNetwork",
                                &error,
                                NULL,
                                "sayssusai",
                                machine_name,
                                SD_BUS_MESSAGE_APPEND_ID128(uuid),
                                service,
                                "container",
                                (uint32_t) pid,
                                strempty(directory),
                                local_ifindex > 0 ? 1 : 0, local_ifindex);
        } else {
                _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;

                r = sd_bus_message_new_method_call(
                                bus,
                                &m,
                                "org.freedesktop.machine1",
                                "/org/freedesktop/machine1",
                                "org.freedesktop.machine1.Manager",
                                "CreateMachineWithNetwork");
                if (r < 0)
                        return bus_log_create_error(r);

                r = sd_bus_message_append(
                                m,
                                "sayssusai",
                                machine_name,
                                SD_BUS_MESSAGE_APPEND_ID128(uuid),
                                service,
                                "container",
                                (uint32_t) pid,
                                strempty(directory),
                                local_ifindex > 0 ? 1 : 0, local_ifindex);
                if (r < 0)
                        return bus_log_create_error(r);

                r = sd_bus_message_open_container(m, 'a', "(sv)");
                if (r < 0)
                        return bus_log_create_error(r);

                if (!isempty(slice)) {
                        r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
                        if (r < 0)
                                return bus_log_create_error(r);
                }

                r = append_controller_property(bus, m);
                if (r < 0)
                        return r;

                r = append_machine_properties(
                                m,
                                mounts,
                                n_mounts,
                                kill_signal,
                                properties);
                if (r < 0)
                        return r;

                r = bus_append_unit_property_assignment_many(m, UNIT_SERVICE, properties);
                if (r < 0)
                        return r;

                r = sd_bus_message_close_container(m);
                if (r < 0)
                        return bus_log_create_error(r);

                r = sd_bus_call(bus, m, 0, &error, NULL);
        }

        if (r < 0) {
                log_error("Failed to register machine: %s", bus_error_message(&error, r));
                return r;
        }

        return 0;
}
Пример #6
0
static void client_chart(Type type, const char *address, const char *server_name, int fd) {
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *x = NULL;
        size_t csize;
        sd_bus *b;
        int r;

        r = sd_bus_new(&b);
        assert_se(r >= 0);

        if (type == TYPE_DIRECT) {
                r = sd_bus_set_fd(b, fd, fd);
                assert_se(r >= 0);
        } else {
                r = sd_bus_set_address(b, address);
                assert_se(r >= 0);

                r = sd_bus_set_bus_client(b, true);
                assert_se(r >= 0);
        }

        r = sd_bus_start(b);
        assert_se(r >= 0);

        r = sd_bus_call_method(b, server_name, "/", "benchmark.server", "Ping", NULL, NULL, NULL);
        assert_se(r >= 0);

        switch (type) {
        case TYPE_KDBUS:
                printf("SIZE\tCOPY\tMEMFD\n");
                break;
        case TYPE_LEGACY:
                printf("SIZE\tLEGACY\n");
                break;
        case TYPE_DIRECT:
                printf("SIZE\tDIRECT\n");
                break;
        }

        for (csize = 1; csize <= MAX_SIZE; csize *= 2) {
                usec_t t;
                unsigned n_copying, n_memfd;

                printf("%zu\t", csize);

                if (type == TYPE_KDBUS) {
                        b->use_memfd = 0;

                        t = now(CLOCK_MONOTONIC);
                        for (n_copying = 0;; n_copying++) {
                                transaction(b, csize, server_name);
                                if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
                                        break;
                        }

                        printf("%u\t", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec));

                        b->use_memfd = -1;
                }

                t = now(CLOCK_MONOTONIC);
                for (n_memfd = 0;; n_memfd++) {
                        transaction(b, csize, server_name);
                        if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
                                break;
                }

                printf("%u\n", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec));
        }

        b->use_memfd = 1;
        assert_se(sd_bus_message_new_method_call(b, &x, server_name, "/", "benchmark.server", "Exit") >= 0);
        assert_se(sd_bus_message_append(x, "t", csize) >= 0);
        assert_se(sd_bus_send(b, x, NULL) >= 0);

        sd_bus_unref(b);
}
// Helper Function to get IP Address/NetMask/Gateway from Network Manager or Cache
// based on Set-In-Progress State
ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t * data)
{
    sd_bus *bus = ipmid_get_sd_bus_connection();
    sd_bus_message *reply = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int family;
    unsigned char prefixlen;
    char* ipaddr = NULL;
    unsigned long mask = 0xFFFFFFFF;
    char* gateway = NULL;
    int r = 0;
    ipmi_ret_t rc = IPMI_CC_OK;

    r = sd_bus_call_method(bus, app, obj, ifc, "GetAddress4", &error,
                            &reply, "s", nwinterface);
    if(r < 0)
    {
        fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
        rc = IPMI_CC_UNSPECIFIED_ERROR;
        goto cleanup;
    }

    r = sd_bus_message_read(reply, "iyss", &family, &prefixlen, &ipaddr, &gateway);
    if(r < 0)
    {
        fprintf(stderr, "Failed to get a response: %s\n", strerror(-rc));
        rc = IPMI_CC_RESPONSE_ERROR;
        goto cleanup;
    }

    printf("N/W data from HW %s:%d:%s:%s\n", family==AF_INET?"IPv4":"IPv6", prefixlen, ipaddr,gateway);
    printf("N/W data from Cache: %s:%s:%s\n", new_ipaddr, new_netmask, new_gateway);

    if(lan_param == LAN_PARM_IP)
    {
        if(lan_set_in_progress == SET_COMPLETE)
        {
            std::string ipaddrstr(ipaddr);
            inet_pton(AF_INET, ipaddrstr.c_str(),(void *)data);
        }
        else if(lan_set_in_progress == SET_IN_PROGRESS)
        {
            inet_pton(AF_INET, new_ipaddr, (void *)data);
        }
    }
    else if(lan_param == LAN_PARM_SUBNET)
    {
        if(lan_set_in_progress == SET_COMPLETE)
         {
            mask = htonl(mask<<(32-prefixlen));
            memcpy(data, &mask, 4);
         }
         else if(lan_set_in_progress == SET_IN_PROGRESS)
         {
             inet_pton(AF_INET, new_netmask, (void *)data);
         }
    }
    else if(lan_param == LAN_PARM_GATEWAY)
    {
        if(lan_set_in_progress == SET_COMPLETE)
         {
            std::string gatewaystr(gateway);
            inet_pton(AF_INET, gatewaystr.c_str(), (void *)data);
         }
         else if(lan_set_in_progress == SET_IN_PROGRESS)
         {
             inet_pton(AF_INET, new_gateway,(void *)data);
         }
    }
    else
    {
        rc = IPMI_CC_PARM_OUT_OF_RANGE;
    }

cleanup:
    sd_bus_error_free(&error);
    reply = sd_bus_message_unref(reply);

    return rc;
}
ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                              ipmi_request_t request, ipmi_response_t response,
                              ipmi_data_len_t data_len, ipmi_context_t context)
{
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = 0;
    sd_bus *bus = ipmid_get_sd_bus_connection();
    sd_bus_message *reply = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int r = 0;

    printf("IPMI SET_LAN\n");

    set_lan_t *reqptr = (set_lan_t*) request;

    // TODO Use dbus interface once available. For now use cmd line.
    // TODO Add the rest of the parameters like setting auth type
    // TODO Add error handling

    if (reqptr->parameter == LAN_PARM_IP)
    {
        snprintf(new_ipaddr, INET_ADDRSTRLEN, "%d.%d.%d.%d",
            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
    }
    else if (reqptr->parameter == LAN_PARM_MAC)
    {
        char mac[SIZE_MAC];

        snprintf(mac, SIZE_MAC, "%02x:%02x:%02x:%02x:%02x:%02x",
                reqptr->data[0],
                reqptr->data[1],
                reqptr->data[2],
                reqptr->data[3],
                reqptr->data[4],
                reqptr->data[5]);

        r = sd_bus_call_method(bus, app, obj, ifc, "SetHwAddress", &error,
                                &reply, "ss", nwinterface, mac);
        if(r < 0)
        {
            fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
            rc = IPMI_CC_UNSPECIFIED_ERROR;
        }
    }
    else if (reqptr->parameter == LAN_PARM_SUBNET)
    {
        snprintf(new_netmask, INET_ADDRSTRLEN, "%d.%d.%d.%d",
            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
    }
    else if (reqptr->parameter == LAN_PARM_GATEWAY)
    {
        snprintf(new_gateway, INET_ADDRSTRLEN, "%d.%d.%d.%d",
            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
    }
    else if (reqptr->parameter == LAN_PARM_INPROGRESS)
    {
        if(reqptr->data[0] == SET_COMPLETE) // Set Complete
        {
            lan_set_in_progress = SET_COMPLETE;
            // Apply the IP settings once IP Address, Netmask and Gateway  is set
            if (!strcmp(new_ipaddr, "") || !strcmp (new_netmask, "") || !strcmp (new_gateway, ""))
            {
                printf("ERROR: Incomplete LAN Parameters\n");
            }
            else
            {

                r = sd_bus_call_method(bus,            // On the System Bus
                                        app,            // Service to contact
                                        obj,            // Object path
                                        ifc,            // Interface name
                                        "SetAddress4",  // Method to be called
                                        &error,         // object to return error
                                        &reply,         // Response message on success
                                        "ssss",         // input message (Interface, IP Address, Netmask, Gateway)
                                        nwinterface,    // eth0
                                        new_ipaddr,
                                        new_netmask,
                                        new_gateway);
                if(r < 0)
                {
                    fprintf(stderr, "Failed to set network data %s:%s:%s %s\n", new_ipaddr, new_netmask, new_gateway, error.message);
                    rc = IPMI_CC_UNSPECIFIED_ERROR;
                }
                memset(new_ipaddr, 0, INET_ADDRSTRLEN);
                memset(new_netmask, 0, INET_ADDRSTRLEN);
                memset(new_gateway, 0, INET_ADDRSTRLEN);
            }
        }
        else if(reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
        {
            lan_set_in_progress = SET_IN_PROGRESS;
        }
    }
    else
    {
        fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
        rc = IPMI_CC_PARM_NOT_SUPPORTED;
    }

    sd_bus_error_free(&error);
    reply = sd_bus_message_unref(reply);

    return rc;
}
Пример #9
0
int bus_verify_polkit(
                sd_bus *bus,
                sd_bus_message *m,
                const char *action,
                bool interactive,
                bool *_challenge,
                sd_bus_error *e) {

        const char *sender;
        uid_t uid;
        int r;

        assert(bus);
        assert(m);
        assert(action);

        sender = sd_bus_message_get_sender(m);
        if (!sender)
                return -EBADMSG;

        r = sd_bus_get_owner_uid(bus, sender, &uid);
        if (r < 0)
                return r;

        if (uid == 0)
                return 1;

#ifdef ENABLE_POLKIT
        else {
                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
                unsigned authorized = false, challenge = false;

                r = sd_bus_call_method(
                                bus,
                                "org.freedesktop.PolicyKit1",
                                "/org/freedesktop/PolicyKit1/Authority",
                                "org.freedesktop.PolicyKit1.Authority",
                                "CheckAuthorization",
                                e,
                                &reply,
                                "(sa{sv})sa{ss}us",
                                "system-bus-name", 1, "name", "s", sender,
                                action,
                                0,
                                interactive ? 1 : 0,
                                "");

                if (r < 0) {
                        /* Treat no PK available as access denied */
                        if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
                                sd_bus_error_free(e);
                                return -EACCES;
                        }

                        return r;
                }

                r = sd_bus_message_read(reply, "(bb)", &authorized, &challenge);
                if (r < 0)
                        return r;

                if (authorized)
                        return 1;

                if (_challenge) {
                        *_challenge = challenge;
                        return 0;
                }
        }
#endif

        return -EACCES;
}
Пример #10
0
//-------------------------------------------------------------------
// Gets called by PowerOff handler when a Soft Power off is requested
//-------------------------------------------------------------------
static int soft_power_off(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
{
    int64_t bt_resp = -1;
    int rc = 0;
    char *bus_name = NULL;

    // Steps to be taken when we get this.
    //  1: Send a SMS_ATN to the Host
    //  2: Host receives it and sends a GetMsgFlags IPMI command
    //  3: IPMID app handler will respond to that with a MSgFlag with bit:0x2
    //     set indicating we have a message for Host
    //  4: Host sends a GetMsgBuffer command and app handler will respond to
    //     that with a OEM-SEL with certain fields packed indicating to the
    //     host that it do a shutdown of the partitions.
    //  5: Host does the partition shutdown and calls Chassis Power off command
    //  6: App handler handles the command by making a call to ChassisManager
    //     Dbus

    // Now the job is to send the SMS_ATTN.

    // Req message contains the specifics about which method etc that we want to
    // access on which bus, object
    sd_bus_message *response = NULL;

    // Error return mechanism
    sd_bus_error bus_error = SD_BUS_ERROR_NULL;

    // Gets a hook onto either a SYSTEM or SESSION bus
    sd_bus *bus = ipmid_get_sd_bus_connection();
    rc = mapper_get_service(bus, object_name, &bus_name);
    if (rc < 0) {
        fprintf(stderr, "Failed to get %s bus name: %s\n",
                object_name, strerror(-rc));
        goto finish;
    }
    rc = sd_bus_call_method(bus,             // In the System Bus
                            bus_name,        // Service to contact
                            object_name,     // Object path
                            intf_name,       // Interface name
                            "setAttention",  // Method to be called
                            &bus_error,      // object to return error
                            &response,       // Response buffer if any
                            NULL);           // No input arguments
    if(rc < 0)
    {
        fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);
        goto finish;
    }

    // See if we were able to successfully raise SMS_ATN
    rc = sd_bus_message_read(response, "x", &bt_resp);
    if (rc < 0)
    {
        fprintf(stderr, "Failed to get a rc from BT for SMS_ATN: %s\n", strerror(-rc));
        goto finish;
    }

finish:
    sd_bus_error_free(&bus_error);
    response = sd_bus_message_unref(response);
    free(bus_name);

    if(rc < 0)
    {
        return sd_bus_reply_method_return(m, "x", rc);
    }
    else
    {
        return sd_bus_reply_method_return(m, "x", bt_resp);
    }
}
Пример #11
0
//-------------------
// Destructor
//-------------------
ipmi_fru::~ipmi_fru()
{
    sd_bus_error bus_error = SD_BUS_ERROR_NULL;
    sd_bus_message *response = NULL;
    int rc = 0;

    if(iv_data != NULL)
    {
        delete [] iv_data;
        iv_data = NULL;
    }

    // If we have not been successful in doing some updates and we are a BMC
    // fru, then need to set the fault bits.
    bool valid_dbus = !(iv_bus_name.empty()) &&
                      !(iv_obj_path.empty()) &&
                      !(iv_intf_name.empty());

    // Based on bmc_fru, success in updating the FRU inventory we need to set
    // some special bits.
    if(iv_bmc_fru && valid_dbus)
    {
        // Set the Fault bit if we did not successfully process the fru
        const char *fault_bit = iv_valid ? "False" : "True";

        rc = sd_bus_call_method(iv_bus_type,                // On the System Bus
                                iv_bus_name.c_str(),        // Service to contact
                                iv_obj_path.c_str(),        // Object path
                                iv_intf_name.c_str(),       // Interface name
                                "setFault",                 // Method to be called
                                &bus_error,                 // object to return error
                                &response,                  // Response message on success
                                "s",                        // input message (string)
                                fault_bit);                 // First argument to setFault

        if(rc <0)
        {
            fprintf(stderr,"Failed to set Fault bit, value:[%s] for fruid:[%d], path:[%s]\n",
                    fault_bit, iv_fruid, iv_obj_path.c_str());
        }
        else
        {
            printf("Fault bit set to :[%s] for fruid:[%d], Path:[%s]\n",
                    fault_bit, iv_fruid,iv_obj_path.c_str());
        }

        sd_bus_error_free(&bus_error);
        sd_bus_message_unref(response);

        // Set the Present bits
        const char *present_bit = iv_present ? "True" : "False";

        rc = sd_bus_call_method(iv_bus_type,                // On the System Bus
                                iv_bus_name.c_str(),        // Service to contact
                                iv_obj_path.c_str(),        // Object path
                                iv_intf_name.c_str(),       // Interface name
                                "setPresent",               // Method to be called
                                &bus_error,                 // object to return error
                                &response,                  // Response message on success
                                "s",                        // input message (string)
                                present_bit);               // First argument to setPresent
        if(rc < 0)
        {
            fprintf(stderr,"Failed to set Present bit for fruid:[%d], path:[%s]\n",
                    iv_fruid, iv_obj_path.c_str());
        }
        else
        {
            printf("Present bit set to :[%s] for fruid:[%d], Path[%s]:\n",
                    present_bit, iv_fruid, iv_obj_path.c_str());
        }

        sd_bus_error_free(&bus_error);
        sd_bus_message_unref(response);
    }
}
Пример #12
0
///-----------------------------------------------------
// Get the fru area names defined in BMC for a given @fruid.
//----------------------------------------------------
int get_defined_fru_area(sd_bus *bus_type, const uint8_t fruid,
                         std::vector<std::string> &defined_fru_area)
{
    // Need this to get respective DBUS objects
    sd_bus_error bus_error = SD_BUS_ERROR_NULL;
    sd_bus_message *response = NULL;
    int rc = 0;
    char *areas = NULL;

#ifdef __IPMI_DEBUG__
    printf("Getting fru areas defined in Skeleton for :[%d]\n", fruid);
#endif

    // We want to call a method "getFRUArea" on System Bus that is
    // made available over OpenBmc system services.
    rc = sd_bus_call_method(bus_type,                   // On the System Bus
                            sys_bus_name,               // Service to contact
                            sys_object_name,            // Object path
                            sys_intf_name,              // Interface name
                            "getFRUArea",               // Method to be called
                            &bus_error,                 // object to return error
                            &response,                  // Response message on success
                            "y",                        // input message (integer)
                            fruid);                     // Argument

    if(rc < 0)
    {
        fprintf(stderr, "Failed to get fru area for fruid:[%d] to dbus: [%s]\n",
                    fruid, bus_error.message);
    }
    else
    {
        // if several fru area names are defined, the names are combined to
        // a string seperated by ','
        rc = sd_bus_message_read(response, "s", &areas);
        if(rc < 0)
        {
            fprintf(stderr, "Failed to parse response message from getFRUArea:[%s]\n",
                        strerror(-rc));
        }
        else
        {
#ifdef __IPMI_DEBUG__
            printf("get defined fru area: id: %d, areas: %s\n", fruid, areas);
#endif
            std::string area_name;
            std::stringstream ss(areas);
            // fru area names string is seperated by ',', parse it into tokens
            while (std::getline(ss, area_name, ','))
            {
                if (!area_name.empty())
                    defined_fru_area.emplace_back(area_name);
            }
        }
    }

    sd_bus_error_free(&bus_error);
    sd_bus_message_unref(response);

    return rc;
}
Пример #13
0
static int start_transient_service(
    sd_bus *bus,
    char **argv,
    int *retval) {

    _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
    _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
    _cleanup_free_ char *service = NULL, *pty_path = NULL;
    _cleanup_close_ int master = -1;
    int r;

    assert(bus);
    assert(argv);
    assert(retval);

    if (arg_pty) {

        if (arg_transport == BUS_TRANSPORT_LOCAL) {
            master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
            if (master < 0)
                return log_error_errno(errno, "Failed to acquire pseudo tty: %m");

            r = ptsname_malloc(master, &pty_path);
            if (r < 0)
                return log_error_errno(r, "Failed to determine tty name: %m");

            if (unlockpt(master) < 0)
                return log_error_errno(errno, "Failed to unlock tty: %m");

        } else if (arg_transport == BUS_TRANSPORT_MACHINE) {
            _cleanup_(sd_bus_unrefp) sd_bus *system_bus = NULL;
            _cleanup_(sd_bus_message_unrefp) sd_bus_message *pty_reply = NULL;
            const char *s;

            r = sd_bus_default_system(&system_bus);
            if (r < 0)
                return log_error_errno(r, "Failed to connect to system bus: %m");

            r = sd_bus_call_method(system_bus,
                                   "org.freedesktop.machine1",
                                   "/org/freedesktop/machine1",
                                   "org.freedesktop.machine1.Manager",
                                   "OpenMachinePTY",
                                   &error,
                                   &pty_reply,
                                   "s", arg_host);
            if (r < 0) {
                log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r));
                return r;
            }

            r = sd_bus_message_read(pty_reply, "hs", &master, &s);
            if (r < 0)
                return bus_log_parse_error(r);

            master = fcntl(master, F_DUPFD_CLOEXEC, 3);
            if (master < 0)
                return log_error_errno(errno, "Failed to duplicate master fd: %m");

            pty_path = strdup(s);
            if (!pty_path)
                return log_oom();
        } else
            assert_not_reached("Can't allocate tty via ssh");
    }

    if (!arg_no_block) {
        r = bus_wait_for_jobs_new(bus, &w);
        if (r < 0)
            return log_error_errno(r, "Could not watch jobs: %m");
    }

    if (arg_unit) {
        r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service);
        if (r < 0)
            return log_error_errno(r, "Failed to mangle unit name: %m");
    } else {
        r = make_unit_name(bus, UNIT_SERVICE, &service);
        if (r < 0)
            return r;
    }

    r = sd_bus_message_new_method_call(
            bus,
            &m,
            "org.freedesktop.systemd1",
            "/org/freedesktop/systemd1",
            "org.freedesktop.systemd1.Manager",
            "StartTransientUnit");
    if (r < 0)
        return bus_log_create_error(r);

    r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
    if (r < 0)
        return bus_log_create_error(r);

    /* Name and mode */
    r = sd_bus_message_append(m, "ss", service, "fail");
    if (r < 0)
        return bus_log_create_error(r);

    /* Properties */
    r = sd_bus_message_open_container(m, 'a', "(sv)");
    if (r < 0)
        return bus_log_create_error(r);

    r = transient_service_set_properties(m, argv, pty_path);
    if (r < 0)
        return bus_log_create_error(r);

    r = sd_bus_message_close_container(m);
    if (r < 0)
        return bus_log_create_error(r);

    /* Auxiliary units */
    r = sd_bus_message_append(m, "a(sa(sv))", 0);
    if (r < 0)
        return bus_log_create_error(r);

    polkit_agent_open_if_enabled();

    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0)
        return log_error_errno(r, "Failed to start transient service unit: %s", bus_error_message(&error, r));

    if (w) {
        const char *object;

        r = sd_bus_message_read(reply, "o", &object);
        if (r < 0)
            return bus_log_parse_error(r);

        r = bus_wait_for_jobs_one(w, object, arg_quiet);
        if (r < 0)
            return r;
    }

    if (!arg_quiet)
        log_info("Running as unit: %s", service);

    if (arg_wait || master >= 0) {
        _cleanup_(run_context_free) RunContext c = {};

        c.bus = sd_bus_ref(bus);

        r = sd_event_default(&c.event);
        if (r < 0)
            return log_error_errno(r, "Failed to get event loop: %m");

        if (master >= 0) {
            assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGWINCH, SIGTERM, SIGINT, -1) >= 0);
            (void) sd_event_add_signal(c.event, NULL, SIGINT, NULL, NULL);
            (void) sd_event_add_signal(c.event, NULL, SIGTERM, NULL, NULL);

            if (!arg_quiet)
                log_info("Press ^] three times within 1s to disconnect TTY.");

            r = pty_forward_new(c.event, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, &c.forward);
            if (r < 0)
                return log_error_errno(r, "Failed to create PTY forwarder: %m");

            pty_forward_set_handler(c.forward, pty_forward_handler, &c);
        }

        if (arg_wait) {
            _cleanup_free_ char *path = NULL;
            const char *mt;

            path = unit_dbus_path_from_name(service);
            if (!path)
                return log_oom();

            mt = strjoina("type='signal',"
                          "sender='org.freedesktop.systemd1',"
                          "path='", path, "',"
                          "interface='org.freedesktop.DBus.Properties',"
                          "member='PropertiesChanged'");
            r = sd_bus_add_match(bus, &c.match, mt, on_properties_changed, &c);
            if (r < 0)
                return log_error_errno(r, "Failed to add properties changed signal.");

            r = sd_bus_attach_event(bus, c.event, 0);
            if (r < 0)
                return log_error_errno(r, "Failed to attach bus to event loop.");
        }

        r = sd_event_loop(c.event);
        if (r < 0)
            return log_error_errno(r, "Failed to run event loop: %m");

        if (c.forward) {
            char last_char = 0;

            r = pty_forward_get_last_char(c.forward, &last_char);
            if (r >= 0 && !arg_quiet && last_char != '\n')
                fputc('\n', stdout);
        }

        if (!arg_quiet) {
            if (!isempty(c.result))
                log_info("Finished with result: %s", strna(c.result));

            if (c.exit_code == CLD_EXITED)
                log_info("Main processes terminated with: code=%s/status=%i", sigchld_code_to_string(c.exit_code), c.exit_status);
            else if (c.exit_code > 0)
                log_info("Main processes terminated with: code=%s/status=%s", sigchld_code_to_string(c.exit_code), signal_to_string(c.exit_status));

            if (c.inactive_enter_usec > 0 && c.inactive_enter_usec != USEC_INFINITY &&
                    c.inactive_exit_usec > 0 && c.inactive_exit_usec != USEC_INFINITY &&
                    c.inactive_enter_usec > c.inactive_exit_usec) {
                char ts[FORMAT_TIMESPAN_MAX];
                log_info("Service runtime: %s", format_timespan(ts, sizeof(ts), c.inactive_enter_usec - c.inactive_exit_usec, USEC_PER_MSEC));
            }

            if (c.cpu_usage_nsec > 0 && c.cpu_usage_nsec != NSEC_INFINITY) {
                char ts[FORMAT_TIMESPAN_MAX];
                log_info("CPU time consumed: %s", format_timespan(ts, sizeof(ts), (c.cpu_usage_nsec + NSEC_PER_USEC - 1) / NSEC_PER_USEC, USEC_PER_MSEC));
            }
        }

        /* Try to propagate the service's return value */
        if (c.result && STR_IN_SET(c.result, "success", "exit-code") && c.exit_code == CLD_EXITED)
            *retval = c.exit_status;
        else
            *retval = EXIT_FAILURE;
    }

    return 0;
}
Пример #14
0
/*
 * First of all, creates a transaction;
 * then reads the newly created bus path,
 * adds a match to the bus to wait until installation is really finished before notifying the user.
 * finally, calls InstallFiles method, and processes the bus while finished == 0.
 */
void *install_package(void *str) {
    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_message *mess = NULL;
    sd_bus *install_bus = NULL;
    const char *path;
    int r, inhibit_fd = -1, finished = 0;
    
    r = sd_bus_open_system(&install_bus);
    if (r < 0) {
        print_and_warn(strerror(-r), ERR_LINE);
        goto finish;
    }
    INFO("calling CreateTransaction on bus.");
    r = sd_bus_call_method(install_bus,
                           "org.freedesktop.PackageKit",
                           "/org/freedesktop/PackageKit",
                           "org.freedesktop.PackageKit",
                           "CreateTransaction",
                           &error,
                           &mess,
                           NULL);
    if (r < 0) {
        print_and_warn(error.message, ERR_LINE);
        goto finish;
    }
    if (config.inhibit) {
        inhibit_fd = inhibit_suspend("Package installation...");
    }
    sd_bus_message_read(mess, "o", &path);
    r = sd_bus_add_match(install_bus, NULL, "type='signal',interface='org.freedesktop.PackageKit.Transaction',member='Finished'", match_callback, &finished);
    if (r < 0) {
        print_and_warn(strerror(-r), ERR_LINE);
        goto finish;
    }
    sd_bus_flush(install_bus);
    INFO("calling InstallFiles on bus.");
    r = sd_bus_call_method(install_bus,
                        "org.freedesktop.PackageKit",
                        path,
                        "org.freedesktop.PackageKit.Transaction",
                        "InstallFiles",
                        &error,
                        NULL,
                        "tas",
                        0,
                        1,
                        (char *)str);
    if (r < 0) {
        print_and_warn(error.message, ERR_LINE);
        goto finish;
    }
    while (!finished) {
        r = sd_bus_process(install_bus, NULL);
        if (r > 0) {
            continue;
        }
        r = sd_bus_wait(install_bus, (uint64_t) -1);
        if (r < 0) {
            break;
        }
    }

finish:
    stop_inhibition(inhibit_fd);
    close_bus(&error, mess, install_bus);
    pthread_detach(pthread_self());
    pthread_exit(NULL);
}
Пример #15
0
enum nss_status _nss_systemd_getgrgid_r(
                gid_t gid,
                struct group *gr,
                char *buffer, size_t buflen,
                int *errnop) {

        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        const char *translated;
        size_t l;
        int r;

        BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);

        if (!gid_is_valid(gid)) {
                r = -EINVAL;
                goto fail;
        }

        if (gid <= SYSTEM_GID_MAX)
                goto not_found;

        if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                goto not_found;

        r = sd_bus_open_system(&bus);
        if (r < 0)
                goto fail;

        r = sd_bus_call_method(bus,
                               "org.freedesktop.systemd1",
                               "/org/freedesktop/systemd1",
                               "org.freedesktop.systemd1.Manager",
                               "LookupDynamicUserByUID",
                               &error,
                               &reply,
                               "u",
                               (uint32_t) gid);
        if (r < 0) {
                if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
                        goto not_found;

                goto fail;
        }

        r = sd_bus_message_read(reply, "s", &translated);
        if (r < 0)
                goto fail;

        l = sizeof(char*) + strlen(translated) + 1;
        if (buflen < l) {
                *errnop = ENOMEM;
                return NSS_STATUS_TRYAGAIN;
        }

        memzero(buffer, sizeof(char*));
        strcpy(buffer + sizeof(char*), translated);

        gr->gr_name = buffer + sizeof(char*);
        gr->gr_gid = gid;
        gr->gr_passwd = (char*) "*"; /* locked */
        gr->gr_mem = (char**) buffer;

        *errnop = 0;
        return NSS_STATUS_SUCCESS;

not_found:
        *errnop = 0;
        return NSS_STATUS_NOTFOUND;

fail:
        *errnop = -r;
        return NSS_STATUS_UNAVAIL;
}
Пример #16
0
enum nss_status _nss_systemd_getpwnam_r(
                const char *name,
                struct passwd *pwd,
                char *buffer, size_t buflen,
                int *errnop) {

        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        uint32_t translated;
        size_t l;
        int r;

        BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);

        assert(name);
        assert(pwd);

        /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
        if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                goto not_found;

        r = sd_bus_open_system(&bus);
        if (r < 0)
                goto fail;

        r = sd_bus_call_method(bus,
                               "org.freedesktop.systemd1",
                               "/org/freedesktop/systemd1",
                               "org.freedesktop.systemd1.Manager",
                               "LookupDynamicUserByName",
                               &error,
                               &reply,
                               "s",
                               name);
        if (r < 0) {
                if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
                        goto not_found;

                goto fail;
        }

        r = sd_bus_message_read(reply, "u", &translated);
        if (r < 0)
                goto fail;

        l = strlen(name);
        if (buflen < l+1) {
                *errnop = ENOMEM;
                return NSS_STATUS_TRYAGAIN;
        }

        memcpy(buffer, name, l+1);

        pwd->pw_name = buffer;
        pwd->pw_uid = (uid_t) translated;
        pwd->pw_gid = (uid_t) translated;
        pwd->pw_gecos = (char*) "Dynamic User";
        pwd->pw_passwd = (char*) "*"; /* locked */
        pwd->pw_dir = (char*) "/";
        pwd->pw_shell = (char*) "/sbin/nologin";

        *errnop = 0;
        return NSS_STATUS_SUCCESS;

not_found:
        *errnop = 0;
        return NSS_STATUS_NOTFOUND;

fail:
        *errnop = -r;
        return NSS_STATUS_UNAVAIL;
}
Пример #17
0
static int acquire_time_data(sd_bus *bus, struct unit_times **out) {
        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        int r, c = 0;
        struct unit_times *unit_times = NULL;
        size_t size = 0;
        UnitInfo u;

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "ListUnits",
                        &error, &reply,
                        NULL);
        if (r < 0) {
                log_error("Failed to list units: %s", bus_error_message(&error, -r));
                goto fail;
        }

        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
        if (r < 0) {
                bus_log_parse_error(r);
                goto fail;
        }

        while ((r = bus_parse_unit_info(reply, &u)) > 0) {
                struct unit_times *t;

                if (!GREEDY_REALLOC(unit_times, size, c+1)) {
                        r = log_oom();
                        goto fail;
                }

                t = unit_times+c;
                t->name = NULL;

                assert_cc(sizeof(usec_t) == sizeof(uint64_t));

                if (bus_get_uint64_property(bus, u.unit_path,
                                            "org.freedesktop.systemd1.Unit",
                                            "InactiveExitTimestampMonotonic",
                                            &t->activating) < 0 ||
                    bus_get_uint64_property(bus, u.unit_path,
                                            "org.freedesktop.systemd1.Unit",
                                            "ActiveEnterTimestampMonotonic",
                                            &t->activated) < 0 ||
                    bus_get_uint64_property(bus, u.unit_path,
                                            "org.freedesktop.systemd1.Unit",
                                            "ActiveExitTimestampMonotonic",
                                            &t->deactivating) < 0 ||
                    bus_get_uint64_property(bus, u.unit_path,
                                            "org.freedesktop.systemd1.Unit",
                                            "InactiveEnterTimestampMonotonic",
                                            &t->deactivated) < 0) {
                        r = -EIO;
                        goto fail;
                }

                if (t->activated >= t->activating)
                        t->time = t->activated - t->activating;
                else if (t->deactivated >= t->activating)
                        t->time = t->deactivated - t->activating;
                else
                        t->time = 0;

                if (t->activating == 0)
                        continue;

                t->name = strdup(u.id);
                if (t->name == NULL) {
                        r = log_oom();
                        goto fail;
                }
                c++;
        }
        if (r < 0) {
                bus_log_parse_error(r);
                goto fail;
        }

        *out = unit_times;
        return c;

fail:
        free_unit_times(unit_times, (unsigned) c);
        return r;
}
ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                              ipmi_request_t request, ipmi_response_t response,
                              ipmi_data_len_t data_len, ipmi_context_t context)
{
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = 0;
    sd_bus *bus = ipmid_get_sd_bus_connection();
    sd_bus_message *reply = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int r = 0;
    const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
    int i = 0;

    printf("IPMI GET_LAN\n");

    get_lan_t *reqptr = (get_lan_t*) request;

    if (reqptr->rev_channel & 0x80) // Revision is bit 7
    {
        // Only current revision was requested
        *data_len = sizeof(current_revision);
        memcpy(response, &current_revision, *data_len);
        return IPMI_CC_OK;
    }

    // TODO Use dbus interface once available. For now use ip cmd.
    // TODO Add the rest of the parameters, like gateway

    if (reqptr->parameter == LAN_PARM_INPROGRESS)
    {
        uint8_t buf[] = {current_revision, lan_set_in_progress};
        *data_len = sizeof(buf);
        memcpy(response, &buf, *data_len);
    }
    else if (reqptr->parameter == LAN_PARM_AUTHSUPPORT)
    {
        uint8_t buf[] = {current_revision,0x04};
        *data_len = sizeof(buf);
        memcpy(response, &buf, *data_len);
    }
    else if (reqptr->parameter == LAN_PARM_AUTHENABLES)
    {
        uint8_t buf[] = {current_revision,0x04,0x04,0x04,0x04,0x04};
        *data_len = sizeof(buf);
        memcpy(response, &buf, *data_len);
    }
    else if ((reqptr->parameter == LAN_PARM_IP) || (reqptr->parameter == LAN_PARM_SUBNET) || (reqptr->parameter == LAN_PARM_GATEWAY))
    {
        uint8_t buf[5];

        *data_len = sizeof(current_revision);
        memcpy(buf, &current_revision, *data_len);

        if(getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
        {
            *data_len = sizeof(buf);
            memcpy(response, &buf, *data_len);
        }
        else
        {
            rc = IPMI_CC_UNSPECIFIED_ERROR;
        }
    }
    else if (reqptr->parameter == LAN_PARM_MAC)
    {
        //string to parse: link/ether xx:xx:xx:xx:xx:xx
        uint8_t buf[7];
        char *eaddr1 = NULL;

        r = sd_bus_call_method(bus, app, obj, ifc, "GetHwAddress", &error,
                                &reply, "s", nwinterface);
        if(r < 0)
        {
            fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
            rc = IPMI_CC_UNSPECIFIED_ERROR;
            goto cleanup;
        }

        r = sd_bus_message_read(reply, "s", &eaddr1);
        if (r < 0)
        {
            fprintf(stderr, "Failed to get a response: %s", strerror(-r));
            rc = IPMI_CC_UNSPECIFIED_ERROR;
            goto cleanup;
        }
        if (eaddr1 == NULL)
        {
            fprintf(stderr, "Failed to get a valid response: %s", strerror(-r));
            rc = IPMI_CC_UNSPECIFIED_ERROR;
            goto cleanup;
        }

        memcpy((void*)&buf[0], &current_revision, 1);

        char *tokptr = NULL;
        char* digit = strtok_r(eaddr1, ":", &tokptr);
        if (digit == NULL)
        {
            fprintf(stderr, "Unexpected MAC format: %s", eaddr1);
            rc = IPMI_CC_RESPONSE_ERROR;
            goto cleanup;
        }

        i=0;
        while (digit != NULL)
        {
            int resp_byte = strtoul(digit, NULL, 16);
            memcpy((void*)&buf[i+1], &resp_byte, 1);
            i++;
            digit = strtok_r(NULL, ":", &tokptr);
        }

        *data_len = sizeof(buf);
        memcpy(response, &buf, *data_len);
    }
    else
    {
        fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
        rc = IPMI_CC_PARM_NOT_SUPPORTED;
    }

cleanup:
    sd_bus_error_free(&error);
    reply = sd_bus_message_unref(reply);

    return rc;
}
Пример #19
0
int dbus_get_property(const char *name, char **buf)
{
    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_message *m = NULL;
    sd_bus *bus = NULL;
    char *temp_buf = NULL;
    char *connection = NULL;
    int r;

    r = object_mapper_get_connection(&connection, settings_object_name);

    if (r < 0) {
        fprintf(stderr, "Failed to get connection, return value: %d.\n", r);
        goto finish;
    }

    printf("connection: %s\n", connection);

    // Get the system bus where most system services are provided.
    bus = ipmid_get_sd_bus_connection();

    /*
     * Bus, service, object path, interface and method are provided to call
     * the method.
     * Signatures and input arguments are provided by the arguments at the
     * end.
     */
    r = sd_bus_call_method(bus,
                           connection,                                 /* service to contact */
                           settings_object_name,                       /* object path */
                           settings_intf_name,                         /* interface name */
                           "Get",                                      /* method name */
                           &error,                                     /* object to return error in */
                           &m,                                         /* return message on success */
                           "ss",                                       /* input signature */
                           host_intf_name,                             /* first argument */
                           name);                                      /* second argument */

    if (r < 0) {
        fprintf(stderr, "Failed to issue method call: %s\n", error.message);
        goto finish;
    }

    /*
     * The output should be parsed exactly the same as the output formatting
     * specified.
     */
    r = sd_bus_message_read(m, "v", "s", &temp_buf);
    if (r < 0) {
        fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
        goto finish;
    }

    asprintf(buf, "%s", temp_buf);
/*    *buf = (char*) malloc(strlen(temp_buf));
    if (*buf) {
        strcpy(*buf, temp_buf);
    }
*/
    printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf);

finish:
    sd_bus_error_free(&error);
    sd_bus_message_unref(m);
    free(connection);

    return r;
}
Пример #20
0
int register_machine(
                const char *machine_name,
                pid_t pid,
                const char *directory,
                sd_id128_t uuid,
                int local_ifindex,
                const char *slice,
                CustomMount *mounts,
                unsigned n_mounts,
                int kill_signal,
                char **properties,
                bool keep_unit) {

        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
        int r;

        r = sd_bus_default_system(&bus);
        if (r < 0)
                return log_error_errno(r, "Failed to open system bus: %m");

        if (keep_unit) {
                r = sd_bus_call_method(
                                bus,
                                "org.freedesktop.machine1",
                                "/org/freedesktop/machine1",
                                "org.freedesktop.machine1.Manager",
                                "RegisterMachineWithNetwork",
                                &error,
                                NULL,
                                "sayssusai",
                                machine_name,
                                SD_BUS_MESSAGE_APPEND_ID128(uuid),
                                "nspawn",
                                "container",
                                (uint32_t) pid,
                                strempty(directory),
                                local_ifindex > 0 ? 1 : 0, local_ifindex);
        } else {
                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
                char **i;
                unsigned j;

                r = sd_bus_message_new_method_call(
                                bus,
                                &m,
                                "org.freedesktop.machine1",
                                "/org/freedesktop/machine1",
                                "org.freedesktop.machine1.Manager",
                                "CreateMachineWithNetwork");
                if (r < 0)
                        return bus_log_create_error(r);

                r = sd_bus_message_append(
                                m,
                                "sayssusai",
                                machine_name,
                                SD_BUS_MESSAGE_APPEND_ID128(uuid),
                                "nspawn",
                                "container",
                                (uint32_t) pid,
                                strempty(directory),
                                local_ifindex > 0 ? 1 : 0, local_ifindex);
                if (r < 0)
                        return bus_log_create_error(r);

                r = sd_bus_message_open_container(m, 'a', "(sv)");
                if (r < 0)
                        return bus_log_create_error(r);

                if (!isempty(slice)) {
                        r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
                        if (r < 0)
                                return bus_log_create_error(r);
                }

                r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "strict");
                if (r < 0)
                        return bus_log_create_error(r);

                /* If you make changes here, also make sure to update
                 * [email protected], to keep the device
                 * policies in sync regardless if we are run with or
                 * without the --keep-unit switch. */
                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9,
                                          /* Allow the container to
                                           * access and create the API
                                           * device nodes, so that
                                           * PrivateDevices= in the
                                           * container can work
                                           * fine */
                                          "/dev/null", "rwm",
                                          "/dev/zero", "rwm",
                                          "/dev/full", "rwm",
                                          "/dev/random", "rwm",
                                          "/dev/urandom", "rwm",
                                          "/dev/tty", "rwm",
                                          "/dev/net/tun", "rwm",
                                          /* Allow the container
                                           * access to ptys. However,
                                           * do not permit the
                                           * container to ever create
                                           * these device nodes. */
                                          "/dev/pts/ptmx", "rw",
                                          "char-pts", "rw");
                if (r < 0)
                        return bus_log_create_error(r);

                for (j = 0; j < n_mounts; j++) {
                        CustomMount *cm = mounts + j;

                        if (cm->type != CUSTOM_MOUNT_BIND)
                                continue;

                        r = is_device_node(cm->source);
                        if (r < 0)
                                return log_error_errno(r, "Failed to stat %s: %m", cm->source);

                        if (r) {
                                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
                                        cm->source, cm->read_only ? "r" : "rw");
                                if (r < 0)
                                        return log_error_errno(r, "Failed to append message arguments: %m");
                        }
                }

                if (kill_signal != 0) {
                        r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
                        if (r < 0)
                                return bus_log_create_error(r);

                        r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
                        if (r < 0)
                                return bus_log_create_error(r);
                }

                STRV_FOREACH(i, properties) {
                        r = sd_bus_message_open_container(m, 'r', "sv");
                        if (r < 0)
                                return bus_log_create_error(r);

                        r = bus_append_unit_property_assignment(m, *i);
                        if (r < 0)
                                return r;

                        r = sd_bus_message_close_container(m);
                        if (r < 0)
                                return bus_log_create_error(r);
                }

                r = sd_bus_message_close_container(m);
                if (r < 0)
                        return bus_log_create_error(r);

                r = sd_bus_call(bus, m, 0, &error, NULL);
        }
Пример #21
0
int object_mapper_get_connection(char **buf, const char *obj_path)
{
    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_message *m = NULL;
    sd_bus *bus = NULL;
    char *temp_buf = NULL, *intf = NULL;
    size_t buf_size = 0;
    int r;

    // Get the system bus where most system services are provided.
    bus = ipmid_get_sd_bus_connection();

    /*
     * Bus, service, object path, interface and method are provided to call
     * the method.
     * Signatures and input arguments are provided by the arguments at the
     * end.
     */
    r = sd_bus_call_method(bus,
                           objmapper_service_name,                      /* service to contact */
                           objmapper_object_name,                       /* object path */
                           objmapper_intf_name,                         /* interface name */
                           "GetObject",                                 /* method name */
                           &error,                                      /* object to return error in */
                           &m,                                          /* return message on success */
                           "s",                                         /* input signature */
                           obj_path                                     /* first argument */
                          );

    if (r < 0) {
        fprintf(stderr, "Failed to issue method call: %s\n", error.message);
        goto finish;
    }

    // Get the key, aka, the connection name
    sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf);

    /*
     * TODO: check the return code. Currently for no reason the message
     * parsing of object mapper is always complaining about
     * "Device or resource busy", but the result seems OK for now. Need
     * further checks.
     * TODO: The following code is preserved in the comments so that it can be
     * resumed after the problem aforementioned is resolved.
     *r = sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf);
     *if (r < 0) {
     *    fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
     *    goto finish;
     *}
     */

    buf_size = strlen(temp_buf) + 1;
    printf("IPMID connection name: %s\n", temp_buf);
    *buf = (char *)malloc(buf_size);

    if (*buf == NULL) {
        fprintf(stderr, "Malloc failed for get_sys_boot_options");
        r = -1;
        goto finish;
    }

    memcpy(*buf, temp_buf, buf_size);

finish:
    sd_bus_error_free(&error);
    sd_bus_message_unref(m);

    return r;
}
Пример #22
0
static void client_bisect(const char *address, const char *server_name) {
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *x = NULL;
        size_t lsize, rsize, csize;
        sd_bus *b;
        int r;

        r = sd_bus_new(&b);
        assert_se(r >= 0);

        r = sd_bus_set_address(b, address);
        assert_se(r >= 0);

        r = sd_bus_start(b);
        assert_se(r >= 0);

        r = sd_bus_call_method(b, server_name, "/", "benchmark.server", "Ping", NULL, NULL, NULL);
        assert_se(r >= 0);

        lsize = 1;
        rsize = MAX_SIZE;

        printf("SIZE\tCOPY\tMEMFD\n");

        for (;;) {
                usec_t t;
                unsigned n_copying, n_memfd;

                csize = (lsize + rsize) / 2;

                if (csize <= lsize)
                        break;

                if (csize <= 0)
                        break;

                printf("%zu\t", csize);

                b->use_memfd = 0;

                t = now(CLOCK_MONOTONIC);
                for (n_copying = 0;; n_copying++) {
                        transaction(b, csize, server_name);
                        if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
                                break;
                }
                printf("%u\t", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec));

                b->use_memfd = -1;

                t = now(CLOCK_MONOTONIC);
                for (n_memfd = 0;; n_memfd++) {
                        transaction(b, csize, server_name);
                        if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
                                break;
                }
                printf("%u\n", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec));

                if (n_copying == n_memfd)
                        break;

                if (n_copying > n_memfd)
                        lsize = csize;
                else
                        rsize = csize;
        }

        b->use_memfd = 1;
        assert_se(sd_bus_message_new_method_call(b, &x, server_name, "/", "benchmark.server", "Exit") >= 0);
        assert_se(sd_bus_message_append(x, "t", csize) >= 0);
        assert_se(sd_bus_send(b, x, NULL) >= 0);

        sd_bus_unref(b);
}
Пример #23
0
int bus_map_all_properties(sd_bus *bus,
                           const char *destination,
                           const char *path,
                           const struct bus_properties_map *map,
                           void *userdata) {
        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(bus);
        assert(destination);
        assert(path);
        assert(map);

        r = sd_bus_call_method( bus,
                        destination,
                        path,
                        "org.freedesktop.DBus.Properties",
                        "GetAll",
                        &error,
                        &m,
                        "s", "");
        if (r < 0)
                return r;

        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
        if (r < 0)
                return r;

        while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
                const struct bus_properties_map *prop;
                const char *member;
                const char *contents;
                void *v;
                unsigned i;

                r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
                if (r < 0)
                        return r;

                for (i = 0, prop = NULL; map[i].member; i++)
                        if (streq(map[i].member, member)) {
                                prop = &map[i];
                                break;
                        }

                if (prop) {
                        r = sd_bus_message_peek_type(m, NULL, &contents);
                        if (r < 0)
                                return r;

                        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
                        if (r < 0)
                                return r;

                        v = (uint8_t *)userdata + prop->offset;
                        if (map[i].set)
                                r = prop->set(bus, member, m, &error, v);
                        else
                                r = map_basic(bus, member, m, &error, v);

                        r = sd_bus_message_exit_container(m);
                        if (r < 0)
                                return r;
                } else {
                        r = sd_bus_message_skip(m, "v");
                        if (r < 0)
                                return r;
                }

                r = sd_bus_message_exit_container(m);
                if (r < 0)
                        return r;
        }

        return r;
}
Пример #24
0
static void* client1(void*p) {
        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        const char *hello;
        int r;
        _cleanup_close_pair_ int pp[2] = { -1, -1 };
        char x;

        r = sd_bus_open_user(&bus);
        if (r < 0) {
                log_error_errno(r, "Failed to connect to user bus: %m");
                goto finish;
        }

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd.test",
                        "/",
                        "org.freedesktop.systemd.test",
                        "LowerCase",
                        &error,
                        &reply,
                        "s",
                        "HELLO");
        if (r < 0) {
                log_error_errno(r, "Failed to issue method call: %m");
                goto finish;
        }

        r = sd_bus_message_read(reply, "s", &hello);
        if (r < 0) {
                log_error_errno(r, "Failed to get string: %m");
                goto finish;
        }

        assert_se(streq(hello, "hello"));

        if (pipe2(pp, O_CLOEXEC|O_NONBLOCK) < 0) {
                log_error_errno(errno, "Failed to allocate pipe: %m");
                r = -errno;
                goto finish;
        }

        log_info("Sending fd=%d", pp[1]);

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd.test",
                        "/",
                        "org.freedesktop.systemd.test",
                        "FileDescriptor",
                        &error,
                        NULL,
                        "h",
                        pp[1]);
        if (r < 0) {
                log_error_errno(r, "Failed to issue method call: %m");
                goto finish;
        }

        errno = 0;
        if (read(pp[0], &x, 1) <= 0) {
                log_error("Failed to read from pipe: %s", errno ? strerror(errno) : "early read");
                goto finish;
        }

        r = 0;

finish:
        if (bus) {
                _cleanup_bus_message_unref_ sd_bus_message *q;

                r = sd_bus_message_new_method_call(
                                bus,
                                &q,
                                "org.freedesktop.systemd.test",
                                "/",
                                "org.freedesktop.systemd.test",
                                "ExitClient1");
                if (r < 0)
                        log_error_errno(r, "Failed to allocate method call: %m");
                else
                        sd_bus_send(bus, q, NULL);

        }

        return INT_TO_PTR(r);
}
Пример #25
0
static int list_images(int argc, char *argv[], void *userdata) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        _cleanup_(table_unrefp) Table *table = NULL;
        int r;

        r = acquire_bus(&bus);
        if (r < 0)
                return r;

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.portable1",
                        "/org/freedesktop/portable1",
                        "org.freedesktop.portable1.Manager",
                        "ListImages",
                        &error,
                        &reply,
                        NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to list images: %s", bus_error_message(&error, r));

        table = table_new("name", "type", "ro", "crtime", "mtime", "usage", "state");
        if (!table)
                return log_oom();

        r = sd_bus_message_enter_container(reply, 'a', "(ssbtttso)");
        if (r < 0)
                return bus_log_parse_error(r);

        for (;;) {
                const char *name, *type, *state;
                uint64_t crtime, mtime, usage;
                TableCell *cell;
                bool ro_bool;
                int ro_int;

                r = sd_bus_message_read(reply, "(ssbtttso)", &name, &type, &ro_int, &crtime, &mtime, &usage, &state, NULL);
                if (r < 0)
                        return bus_log_parse_error(r);
                if (r == 0)
                        break;

                r = table_add_many(table,
                                   TABLE_STRING, name,
                                   TABLE_STRING, type);
                if (r < 0)
                        return log_error_errno(r, "Failed to add row to table: %m");

                ro_bool = ro_int;
                r = table_add_cell(table, &cell, TABLE_BOOLEAN, &ro_bool);
                if (r < 0)
                        return log_error_errno(r, "Failed to add row to table: %m");

                if (ro_bool) {
                        r = table_set_color(table, cell, ansi_highlight_red());
                        if (r < 0)
                                return log_error_errno(r, "Failed to set table cell color: %m");
                }

                r = table_add_many(table,
                                   TABLE_TIMESTAMP, crtime,
                                   TABLE_TIMESTAMP, mtime,
                                   TABLE_SIZE, usage);
                if (r < 0)
                        return log_error_errno(r, "Failed to add row to table: %m");

                r = table_add_cell(table, &cell, TABLE_STRING, state);
                if (r < 0)
                        return log_error_errno(r, "Failed to add row to table: %m");

                if (!streq(state, "detached")) {
                        r = table_set_color(table, cell, ansi_highlight_green());
                        if (r < 0)
                                return log_error_errno(r, "Failed to set table cell color: %m");
                }
        }

        r = sd_bus_message_exit_container(reply);
        if (r < 0)
                return bus_log_parse_error(r);

        if (table_get_rows(table) > 1) {
                r = table_set_sort(table, (size_t) 0, (size_t) -1);
                if (r < 0)
                        return log_error_errno(r, "Failed to sort table: %m");

                table_set_header(table, arg_legend);

                r = table_print(table, NULL);
                if (r < 0)
                        return log_error_errno(r, "Failed to show table: %m");
        }

        if (arg_legend) {
                if (table_get_rows(table) > 1)
                        printf("\n%zu images listed.\n", table_get_rows(table) - 1);
                else
                        printf("No images.\n");
        }

        return 0;
}
Пример #26
0
int bus_verify_polkit(
                sd_bus_message *call,
                int capability,
                const char *action,
                bool interactive,
                bool *_challenge,
                sd_bus_error *e) {

        int r;

        assert(call);
        assert(action);

        r = sd_bus_query_sender_privilege(call, capability);
        if (r < 0)
                return r;
        else if (r > 0)
                return 1;
#ifdef ENABLE_POLKIT
        else {
                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
                int authorized = false, challenge = false;
                const char *sender;

                sender = sd_bus_message_get_sender(call);
                if (!sender)
                        return -EBADMSG;

                r = sd_bus_call_method(
                                call->bus,
                                "org.freedesktop.PolicyKit1",
                                "/org/freedesktop/PolicyKit1/Authority",
                                "org.freedesktop.PolicyKit1.Authority",
                                "CheckAuthorization",
                                e,
                                &reply,
                                "(sa{sv})sa{ss}us",
                                "system-bus-name", 1, "name", "s", sender,
                                action,
                                0,
                                interactive ? 1 : 0,
                                "");

                if (r < 0) {
                        /* Treat no PK available as access denied */
                        if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
                                sd_bus_error_free(e);
                                return -EACCES;
                        }

                        return r;
                }

                r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
                if (r < 0)
                        return r;

                r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
                if (r < 0)
                        return r;

                if (authorized)
                        return 1;

                if (_challenge) {
                        *_challenge = challenge;
                        return 0;
                }
        }
#endif

        return -EACCES;
}
Пример #27
0
int main(int argc, char *argv[]) {
        _cleanup_close_ int bus_ref = -1;
        _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL, *bname = NULL;
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        const char *ua = NULL, *ub = NULL, *the_string = NULL;
        sd_bus *a, *b;
        int r, pipe_fds[2];
        const char *nn;

        log_set_max_level(LOG_DEBUG);

        assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);

        bus_ref = bus_kernel_create_bus(name, false, &bus_name);
        if (bus_ref == -ENOENT)
                return EXIT_TEST_SKIP;

        assert_se(bus_ref >= 0);

        address = strappend("kernel:path=", bus_name);
        assert_se(address);

        r = sd_bus_new(&a);
        assert_se(r >= 0);

        r = sd_bus_new(&b);
        assert_se(r >= 0);

        r = sd_bus_set_description(a, "a");
        assert_se(r >= 0);

        r = sd_bus_set_address(a, address);
        assert_se(r >= 0);

        r = sd_bus_set_address(b, address);
        assert_se(r >= 0);

        assert_se(sd_bus_negotiate_timestamp(a, 1) >= 0);
        assert_se(sd_bus_negotiate_creds(a, true, _SD_BUS_CREDS_ALL) >= 0);

        assert_se(sd_bus_negotiate_timestamp(b, 0) >= 0);
        assert_se(sd_bus_negotiate_creds(b, true, 0) >= 0);

        r = sd_bus_start(a);
        assert_se(r >= 0);

        r = sd_bus_start(b);
        assert_se(r >= 0);

        assert_se(sd_bus_negotiate_timestamp(b, 1) >= 0);
        assert_se(sd_bus_negotiate_creds(b, true, _SD_BUS_CREDS_ALL) >= 0);

        r = sd_bus_get_unique_name(a, &ua);
        assert_se(r >= 0);
        printf("unique a: %s\n", ua);

        r = sd_bus_get_description(a, &nn);
        assert_se(r >= 0);
        printf("name of a: %s\n", nn);

        r = sd_bus_get_unique_name(b, &ub);
        assert_se(r >= 0);
        printf("unique b: %s\n", ub);

        r = sd_bus_get_description(b, &nn);
        assert_se(r >= 0);
        printf("name of b: %s\n", nn);

        assert_se(bus_kernel_get_bus_name(b, &bname) >= 0);
        assert_se(endswith(bname, name));

        r = sd_bus_call_method(a, "this.doesnt.exist", "/foo", "meh.mah", "muh", &error, NULL, "s", "yayayay");
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_SERVICE_UNKNOWN));
        assert_se(r == -EHOSTUNREACH);

        r = sd_bus_add_match(b, NULL, "interface='waldo.com',member='Piep'", NULL, NULL);
        assert_se(r >= 0);

        r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name");
        assert_se(r >= 0);

        r = sd_bus_try_close(b);
        assert_se(r == -EBUSY);

        r = sd_bus_process_priority(b, -10, &m);
        assert_se(r == 0);

        r = sd_bus_process(b, &m);
        assert_se(r > 0);
        assert_se(m);

        bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
        assert_se(sd_bus_message_rewind(m, true) >= 0);

        r = sd_bus_message_read(m, "s", &the_string);
        assert_se(r >= 0);
        assert_se(streq(the_string, "I am a string"));

        sd_bus_message_unref(m);
        m = NULL;

        r = sd_bus_request_name(a, "net.x0pointer.foobar", 0);
        assert_se(r >= 0);

        r = sd_bus_message_new_method_call(b, &m, "net.x0pointer.foobar", "/a/path", "an.inter.face", "AMethod");
        assert_se(r >= 0);

        assert_se(pipe2(pipe_fds, O_CLOEXEC) >= 0);

        assert_se(write(pipe_fds[1], "x", 1) == 1);

        pipe_fds[1] = safe_close(pipe_fds[1]);

        r = sd_bus_message_append(m, "h", pipe_fds[0]);
        assert_se(r >= 0);

        pipe_fds[0] = safe_close(pipe_fds[0]);

        r = sd_bus_send(b, m, NULL);
        assert_se(r >= 0);

        for (;;) {
                sd_bus_message_unref(m);
                m = NULL;
                r = sd_bus_process(a, &m);
                assert_se(r > 0);
                assert_se(m);

                bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
                assert_se(sd_bus_message_rewind(m, true) >= 0);

                if (sd_bus_message_is_method_call(m, "an.inter.face", "AMethod")) {
                        int fd;
                        char x;

                        r = sd_bus_message_read(m, "h", &fd);
                        assert_se(r >= 0);

                        assert_se(read(fd, &x, 1) == 1);
                        assert_se(x == 'x');
                        break;
                }
        }

        r = sd_bus_release_name(a, "net.x0pointer.foobar");
        assert_se(r >= 0);

        r = sd_bus_release_name(a, "net.x0pointer.foobar");
        assert_se(r == -ESRCH);

        r = sd_bus_try_close(a);
        assert_se(r >= 0);

        sd_bus_unref(a);
        sd_bus_unref(b);

        return 0;
}
Пример #28
0
static int manager_connect_bus(Manager *m) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        int r;

        assert(m);
        assert(!m->bus);

        r = sd_bus_default_system(&m->bus);
        if (r < 0)
                return log_error_errno(r, "Failed to connect to system bus: %m");

        r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
        if (r < 0)
                return log_error_errno(r, "Failed to add manager object vtable: %m");

        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
        if (r < 0)
                return log_error_errno(r, "Failed to add machine object vtable: %m");

        r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
        if (r < 0)
                return log_error_errno(r, "Failed to add machine enumerator: %m");

        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m);
        if (r < 0)
                return log_error_errno(r, "Failed to add image object vtable: %m");

        r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m);
        if (r < 0)
                return log_error_errno(r, "Failed to add image enumerator: %m");

        r = sd_bus_add_match(m->bus,
                             NULL,
                             "type='signal',"
                             "sender='org.freedesktop.systemd1',"
                             "interface='org.freedesktop.systemd1.Manager',"
                             "member='JobRemoved',"
                             "path='/org/freedesktop/systemd1'",
                             match_job_removed,
                             m);
        if (r < 0)
                return log_error_errno(r, "Failed to add match for JobRemoved: %m");

        r = sd_bus_add_match(m->bus,
                             NULL,
                             "type='signal',"
                             "sender='org.freedesktop.systemd1',"
                             "interface='org.freedesktop.systemd1.Manager',"
                             "member='UnitRemoved',"
                             "path='/org/freedesktop/systemd1'",
                             match_unit_removed,
                             m);
        if (r < 0)
                return log_error_errno(r, "Failed to add match for UnitRemoved: %m");

        r = sd_bus_add_match(m->bus,
                             NULL,
                             "type='signal',"
                             "sender='org.freedesktop.systemd1',"
                             "interface='org.freedesktop.DBus.Properties',"
                             "member='PropertiesChanged',"
                             "arg0='org.freedesktop.systemd1.Unit'",
                             match_properties_changed,
                             m);
        if (r < 0)
                return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");

        r = sd_bus_add_match(m->bus,
                             NULL,
                             "type='signal',"
                             "sender='org.freedesktop.systemd1',"
                             "interface='org.freedesktop.systemd1.Manager',"
                             "member='Reloading',"
                             "path='/org/freedesktop/systemd1'",
                             match_reloading,
                             m);
        if (r < 0)
                return log_error_errno(r, "Failed to add match for Reloading: %m");

        r = sd_bus_call_method(
                        m->bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "Subscribe",
                        &error,
                        NULL, NULL);
        if (r < 0) {
                log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
                return r;
        }

        r = sd_bus_request_name(m->bus, "org.freedesktop.machine1", 0);
        if (r < 0)
                return log_error_errno(r, "Failed to register name: %m");

        r = sd_bus_attach_event(m->bus, m->event, 0);
        if (r < 0)
                return log_error_errno(r, "Failed to attach bus to event loop: %m");

        return 0;
}
Пример #29
0
enum nss_status _nss_systemd_getpwuid_r(
                uid_t uid,
                struct passwd *pwd,
                char *buffer, size_t buflen,
                int *errnop) {

        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        const char *translated;
        size_t l;
        int r;

        BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);

        if (!uid_is_valid(uid)) {
                r = -EINVAL;
                goto fail;
        }

        if (uid <= SYSTEM_UID_MAX)
                goto not_found;

        if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
                goto not_found;

        r = sd_bus_open_system(&bus);
        if (r < 0)
                goto fail;

        r = sd_bus_call_method(bus,
                               "org.freedesktop.systemd1",
                               "/org/freedesktop/systemd1",
                               "org.freedesktop.systemd1.Manager",
                               "LookupDynamicUserByUID",
                               &error,
                               &reply,
                               "u",
                               (uint32_t) uid);
        if (r < 0) {
                if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
                        goto not_found;

                goto fail;
        }

        r = sd_bus_message_read(reply, "s", &translated);
        if (r < 0)
                goto fail;

        l = strlen(translated) + 1;
        if (buflen < l) {
                *errnop = ENOMEM;
                return NSS_STATUS_TRYAGAIN;
        }

        memcpy(buffer, translated, l);

        pwd->pw_name = buffer;
        pwd->pw_uid = uid;
        pwd->pw_gid = uid;
        pwd->pw_gecos = (char*) "Dynamic User";
        pwd->pw_passwd = (char*) "*"; /* locked */
        pwd->pw_dir = (char*) "/";
        pwd->pw_shell = (char*) "/sbin/nologin";

        *errnop = 0;
        return NSS_STATUS_SUCCESS;

not_found:
        *errnop = 0;
        return NSS_STATUS_NOTFOUND;

fail:
        *errnop = -r;
        return NSS_STATUS_UNAVAIL;
}