예제 #1
0
int terminate_scope(
                sd_bus *bus,
                const char *machine_name) {

        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_free_ char *scope = NULL;
        int r;

        r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope);
        if (r < 0)
                return log_error_errno(r, "Failed to mangle scope name: %m");

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "AbandonScope",
                        &error,
                        NULL,
                        "s",
                        scope);
        if (r < 0) {
                log_debug_errno(r, "Failed to abandon scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
                sd_bus_error_free(&error);
        }

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "KillUnit",
                        &error,
                        NULL,
                        "ssi",
                        scope,
                        "all",
                        (int32_t) SIGKILL);
        if (r < 0) {
                log_debug_errno(r, "Failed to SIGKILL scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
                sd_bus_error_free(&error);
        }

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "UnrefUnit",
                        &error,
                        NULL,
                        "s",
                        scope);
        if (r < 0)
                log_debug_errno(r, "Failed to drop reference to scope '%s', ignoring: %s", scope, bus_error_message(&error, r));

        return 0;
}
예제 #2
0
// Sets up the sd_bus structures for the given fru type
int ipmi_fru::setup_sd_bus_paths(void)
{
    // Need this to get respective DBUS objects
    sd_bus_error bus_error = SD_BUS_ERROR_NULL;
    sd_bus_message *response = NULL;
    int rc = 0;

    // What we need is BOARD_1, PRODUCT_1, CHASSIS_1 etc..
    char *inv_bus_name, *inv_obj_path, *inv_intf_name;
    char fru_area_name[16] = {0};
    sprintf(fru_area_name,"%s%d",iv_name.c_str(), iv_fruid);

#ifdef __IPMI_DEBUG__
    printf("Getting sd_bus for :[%s]\n",fru_area_name);
#endif

    // We want to call a method "getObjectFromId" on System Bus that is
    // made available over  OpenBmc system services.

    rc = sd_bus_call_method(iv_bus_type,                // On the System Bus
                            sys_bus_name,               // Service to contact
                            sys_object_name,            // Object path
                            sys_intf_name,              // Interface name
                            "getObjectFromId",          // Method to be called
                            &bus_error,                 // object to return error
                            &response,                  // Response message on success
                            "ss",                       // input message (string,string)
                            "FRU_STR",                  // First argument to getObjectFromId
                            fru_area_name);             // Second Argument
    if(rc < 0)
    {
        fprintf(stderr, "Failed to resolve fruid:[%d] to dbus: [%s]\n", iv_fruid, bus_error.message);
    }
    else
    {
        // 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.
        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));
        }
        else
        {
            // Update the paths in the area object
            update_dbus_paths(inv_bus_name, inv_obj_path, inv_intf_name);
        }
    }

#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

    sd_bus_error_free(&bus_error);
    sd_bus_message_unref(response);

    return rc;
}
예제 #3
0
ipmi_ret_t ipmi_app_reset_watchdog(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)
{
    const char  *busname = "org.openbmc.watchdog.Host";
    const char  *objname = "/org/openbmc/watchdog/host0";
    const char  *iface = "org.openbmc.Watchdog";
    sd_bus_message *reply = NULL, *m = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int r = 0;

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = 0;

    printf("WATCHDOG RESET\n");

    // Refresh watchdog
    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"poke");
    if (r < 0) {
        fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
        return -1;
    }
    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0) {
        fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
        return -1;
    }

    sd_bus_error_free(&error);
    sd_bus_message_unref(m);

    return rc;
}
예제 #4
0
void lvmnotify_send(struct cmd_context *cmd)
{
	static const char _dbus_notification_failed_msg[] = "D-Bus notification failed";
	sd_bus *bus = NULL;
	sd_bus_message *m = NULL;
	sd_bus_error error = SD_BUS_ERROR_NULL;
	const char *cmd_name;
	int ret;
	int result = 0;

	if (!cmd->vg_notify && !cmd->lv_notify && !cmd->pv_notify)
		return;

	cmd->vg_notify = 0;
	cmd->lv_notify = 0;
	cmd->pv_notify = 0;

	cmd_name = get_cmd_name();

	ret = sd_bus_open_system(&bus);
	if (ret < 0) {
		log_debug_dbus("Failed to connect to dbus: %d", ret);
		return;
	}

	log_debug_dbus("Nofify dbus at %s.", LVM_DBUS_DESTINATION);

	ret = sd_bus_call_method(bus,
				 LVM_DBUS_DESTINATION,
				 LVM_DBUS_PATH,
				 LVM_DBUS_INTERFACE,
				 "ExternalEvent",
				 &error,
				 &m,
				 "s",
				 cmd_name);

	if (ret < 0) {
		if (sd_bus_error_has_name(&error, SD_BUS_SYSTEMD_NO_SUCH_UNIT_ERROR) ||
		    sd_bus_error_has_name(&error, SD_BUS_DBUS_SERVICE_UNKNOWN_ERROR))
			log_debug_dbus("%s: %s", _dbus_notification_failed_msg, error.message);
		else
			log_warn("WARNING: %s: %s", _dbus_notification_failed_msg, error.message);
		goto out;
	}

	ret = sd_bus_message_read(m, "i", &result);
	if (ret < 0)
		log_debug_dbus("Failed to parse dbus response message: %d", ret);
	if (result)
		log_debug_dbus("Bad return value from dbus service: %d", result);
out:
	sd_bus_error_free(&error);
	sd_bus_message_unref(m);
	sd_bus_flush_close_unref(bus);
}
예제 #5
0
int dbus_set_property(const char * name, const char *value)
{
    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_message *m = NULL;
    sd_bus *bus = 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 */
                           "Set",                                      /* method name */
                           &error,                                     /* object to return error in */
                           &m,                                         /* return message on success */
                           "ssv",                                      /* input signature */
                           host_intf_name,                             /* first argument */
                           name,                                       /* second argument */
                           "s",                                        /* third argument */
                           value);                                     /* fourth argument */

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

    printf("IPMID boot option property set: {%s}.\n", value);

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

    return r;
}
예제 #6
0
static void stop_scope_unit(sd_bus *connection, const char *unit_name) {
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int rc = sd_bus_call_method(connection, systemd_bus_name, systemd_path_name, manager_interface,
                                "StopUnit", &error, NULL, "ss", unit_name, "fail");
    if (rc < 0) {
        if (sd_bus_error_is_set(&error)) {
            // NoSuchUnit errors are expected as the contained processes can die at any point.
            if (strcmp(error.name, "org.freedesktop.systemd1.NoSuchUnit"))
                errx(EXIT_FAILURE, "%s", error.message);
            sd_bus_error_free(&error);
        } else
            errx(EXIT_FAILURE, "%s", strerror(-rc));
    }
}
예제 #7
0
int cc_Calculator_split(
    struct cc_client_Calculator *instance, double value, int32_t *whole, int32_t *fraction)
{
    int result = 0;
    struct cc_instance *i;
    sd_bus_message *message = NULL;
    sd_bus_message *reply = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;

    CC_LOG_DEBUG("invoked cc_Calculator_split()\n");
    assert(instance);
    i = instance->instance;
    assert(i && i->backend && i->backend->bus);
    assert(i->service && i->path && i->interface);

    if (instance->split_reply_slot) {
        CC_LOG_ERROR("unable to call method with already pending reply\n");
        return -EBUSY;
    }
    assert(!instance->split_reply_callback);

    result = sd_bus_call_method(
        i->backend->bus, i->service, i->path, i->interface,
        "split", &error, &reply, "d", value);
    if (result < 0) {
        CC_LOG_ERROR("unable to call method: %s\n", strerror(-result));
        goto fail;
    }
    result = sd_bus_message_read(reply, "ii", whole, fraction);
    if (result < 0) {
        CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result));
        goto fail;
    }
    CC_LOG_DEBUG("returning whole=%" PRId32 ", fraction=%" PRId32 "\n", *whole, *fraction);

fail:
    sd_bus_error_free(&error);
    reply = sd_bus_message_unref(reply);
    message = sd_bus_message_unref(message);

    return result;
}
예제 #8
0
int cc_Ball_grab(struct cc_client_Ball *instance, bool *success)
{
    int result = 0;
    struct cc_instance *i;
    sd_bus_message *message = NULL;
    sd_bus_message *reply = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int success_int;

    CC_LOG_DEBUG("invoked cc_Ball_grab()\n");
    assert(instance);
    i = instance->instance;
    assert(i && i->backend && i->backend->bus);
    assert(i->service && i->path && i->interface);

    if (instance->grab_reply_slot) {
        CC_LOG_ERROR("unable to call method with already pending reply\n");
        return -EBUSY;
    }
    assert(!instance->grab_reply_callback);

    result = sd_bus_call_method(
        i->backend->bus, i->service, i->path, i->interface, "grab", &error, &reply, "");
    if (result < 0) {
        CC_LOG_ERROR("unable to call method: %s\n", strerror(-result));
        goto fail;
    }
    result = sd_bus_message_read(reply, "b", &success_int);
    if (result < 0) {
        CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result));
        goto fail;
    }
    *success = !!success_int;
    CC_LOG_DEBUG("returning success=%d\n", (int) *success);

fail:
    sd_bus_error_free(&error);
    reply = sd_bus_message_unref(reply);
    message = sd_bus_message_unref(message);

    return result;
}
예제 #9
0
//------------------------------------------------------------
// Calls into Chassis Control Dbus object to do the power off
//------------------------------------------------------------
int ipmi_chassis_power_control(const char *method)
{
    // sd_bus error
    int rc = 0;

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

    // Response from the call. Although there is no response for this call,
    // obligated to mention this to make compiler happy.
    sd_bus_message *response = NULL;

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

    rc = sd_bus_call_method(bus_type,        		 // On the System Bus
                            chassis_bus_name,        // Service to contact
                            chassis_object_name,     // Object path
                            chassis_intf_name,       // Interface name
                            method,      		 // 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);
    }
    else
    {
        printf("Chassis Power Off initiated successfully\n");
    }

    sd_bus_error_free(&bus_error);
    sd_bus_message_unref(response);

    return rc;
}
예제 #10
0
static void test_error(void) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL;
        const sd_bus_error const_error = SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FILE_EXISTS, "const error");
        const sd_bus_error temporarily_const_error = {
                .name = SD_BUS_ERROR_ACCESS_DENIED,
                .message = "oh! no",
                ._need_free = -1
        };

        assert_se(!sd_bus_error_is_set(&error));
        assert_se(sd_bus_error_set(&error, SD_BUS_ERROR_NOT_SUPPORTED, "xxx") == -EOPNOTSUPP);
        assert_se(streq(error.name, SD_BUS_ERROR_NOT_SUPPORTED));
        assert_se(streq(error.message, "xxx"));
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_NOT_SUPPORTED));
        assert_se(sd_bus_error_get_errno(&error) == EOPNOTSUPP);
        assert_se(sd_bus_error_is_set(&error));
        sd_bus_error_free(&error);

        assert_se(!sd_bus_error_is_set(&error));
        assert_se(sd_bus_error_setf(&error, SD_BUS_ERROR_FILE_NOT_FOUND, "yyy %i", -1) == -ENOENT);
        assert_se(streq(error.name, SD_BUS_ERROR_FILE_NOT_FOUND));
        assert_se(streq(error.message, "yyy -1"));
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_FILE_NOT_FOUND));
        assert_se(sd_bus_error_get_errno(&error) == ENOENT);
        assert_se(sd_bus_error_is_set(&error));

        assert_se(!sd_bus_error_is_set(&second));
        assert_se(second._need_free == 0);
        assert_se(error._need_free > 0);
        assert_se(sd_bus_error_copy(&second, &error) == -ENOENT);
        assert_se(second._need_free > 0);
        assert_se(streq(error.name, second.name));
        assert_se(streq(error.message, second.message));
        assert_se(sd_bus_error_get_errno(&second) == ENOENT);
        assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_NOT_FOUND));
        assert_se(sd_bus_error_is_set(&second));

        sd_bus_error_free(&error);
        sd_bus_error_free(&second);

        assert_se(!sd_bus_error_is_set(&second));
        assert_se(const_error._need_free == 0);
        assert_se(sd_bus_error_copy(&second, &const_error) == -EEXIST);
        assert_se(second._need_free == 0);
        assert_se(streq(const_error.name, second.name));
        assert_se(streq(const_error.message, second.message));
        assert_se(sd_bus_error_get_errno(&second) == EEXIST);
        assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_EXISTS));
        assert_se(sd_bus_error_is_set(&second));
        sd_bus_error_free(&second);

        assert_se(!sd_bus_error_is_set(&second));
        assert_se(temporarily_const_error._need_free < 0);
        assert_se(sd_bus_error_copy(&second, &temporarily_const_error) == -EACCES);
        assert_se(second._need_free > 0);
        assert_se(streq(temporarily_const_error.name, second.name));
        assert_se(streq(temporarily_const_error.message, second.message));
        assert_se(sd_bus_error_get_errno(&second) == EACCES);
        assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_ACCESS_DENIED));
        assert_se(sd_bus_error_is_set(&second));

        assert_se(!sd_bus_error_is_set(&error));
        assert_se(sd_bus_error_set_const(&error, "System.Error.EUCLEAN", "Hallo") == -EUCLEAN);
        assert_se(streq(error.name, "System.Error.EUCLEAN"));
        assert_se(streq(error.message, "Hallo"));
        assert_se(sd_bus_error_has_name(&error, "System.Error.EUCLEAN"));
        assert_se(sd_bus_error_get_errno(&error) == EUCLEAN);
        assert_se(sd_bus_error_is_set(&error));
        sd_bus_error_free(&error);

        assert_se(!sd_bus_error_is_set(&error));
        assert_se(sd_bus_error_set_errno(&error, EBUSY) == -EBUSY);
        assert_se(streq(error.name, "System.Error.EBUSY"));
        assert_se(streq(error.message, strerror(EBUSY)));
        assert_se(sd_bus_error_has_name(&error, "System.Error.EBUSY"));
        assert_se(sd_bus_error_get_errno(&error) == EBUSY);
        assert_se(sd_bus_error_is_set(&error));
        sd_bus_error_free(&error);

        assert_se(!sd_bus_error_is_set(&error));
        assert_se(sd_bus_error_set_errnof(&error, EIO, "Waldi %c", 'X') == -EIO);
        assert_se(streq(error.name, SD_BUS_ERROR_IO_ERROR));
        assert_se(streq(error.message, "Waldi X"));
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_IO_ERROR));
        assert_se(sd_bus_error_get_errno(&error) == EIO);
        assert_se(sd_bus_error_is_set(&error));
}

extern const sd_bus_error_map __start_BUS_ERROR_MAP[];
extern const sd_bus_error_map __stop_BUS_ERROR_MAP[];

static void dump_mapping_table(void) {
        const sd_bus_error_map *m;

        printf("----- errno mappings ------\n");
        m = __start_BUS_ERROR_MAP;
        while (m < __stop_BUS_ERROR_MAP) {

                if (m->code == BUS_ERROR_MAP_END_MARKER) {
                        m = ALIGN8_PTR(m+1);
                        continue;
                }

                printf("%s -> %i/%s\n", strna(m->name), m->code, strna(errno_to_name(m->code)));
                m ++;
        }
        printf("---------------------------\n");
}

static void test_errno_mapping_standard(void) {
        assert_se(sd_bus_error_set(NULL, "System.Error.EUCLEAN", NULL) == -EUCLEAN);
        assert_se(sd_bus_error_set(NULL, "System.Error.EBUSY", NULL) == -EBUSY);
        assert_se(sd_bus_error_set(NULL, "System.Error.EINVAL", NULL) == -EINVAL);
        assert_se(sd_bus_error_set(NULL, "System.Error.WHATSIT", NULL) == -EIO);
}
예제 #11
0
ipmi_ret_t ipmi_app_get_device_guid(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)
{
    const char  *busname = "org.openbmc.control.Chassis";
    const char  *objname = "/org/openbmc/control/chassis0";
    const char  *iface = "org.freedesktop.DBus.Properties";
    const char  *chassis_iface = "org.openbmc.control.Chassis";
    sd_bus_message *reply = NULL, *m = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int r = 0;
    char *uuid = NULL;

    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = 0;

    printf("IPMI GET DEVICE GUID\n");

    // Call Get properties method with the interface and property name
    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"Get");
    if (r < 0) {
        fprintf(stderr, "Failed to add the Get method object: %s\n", strerror(-r));
        return IPMI_CC_UNSPECIFIED_ERROR;
    }
    r = sd_bus_message_append(m, "ss", chassis_iface, "uuid");
    if (r < 0) {
        fprintf(stderr, "Failed to append arguments: %s\n", strerror(-r));
        return -1;
    }
    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0) {
        fprintf(stderr, "Failed to call the Get method: %s\n", strerror(-r));
        return IPMI_CC_UNSPECIFIED_ERROR;
    }
    r = sd_bus_message_read(reply, "v", "s", &uuid);
    if (r < 0) {
        fprintf(stderr, "Failed to get a response: %s", strerror(-r));
        return IPMI_CC_RESPONSE_ERROR;
    }
    if (uuid == NULL)
    {
        fprintf(stderr, "Failed to get a valid response: %s", strerror(-r));
        return IPMI_CC_RESPONSE_ERROR;
    }

    // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
    // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte order
    // Ex: 0x2332fc2c40e66298e511f2782395a361

    const int resp_size = 16; // Response is 16 hex bytes per IPMI Spec
    uint8_t resp_uuid[resp_size]; // Array to hold the formatted response
    int resp_loc = resp_size-1; // Point resp end of array to save in reverse order
    int i = 0;
    char *tokptr = NULL;

    // Traverse the UUID
    char* id_octet = strtok_r(uuid, "-", &tokptr); // Get the UUID octects separated by dash

    if (id_octet == NULL)
    { // Error
        fprintf(stderr, "Unexpected UUID format: %s", uuid);
        return IPMI_CC_RESPONSE_ERROR;
    }

    while (id_octet != NULL)
    {
        // Calculate the octet string size since it varies
        // Divide it by 2 for the array size since 1 byte is built from 2 chars
        int tmp_size = strlen(id_octet)/2;

        for(i = 0; i < tmp_size; i++)
        {
            char tmp_array[3] = {0}; // Holder of the 2 chars that will become a byte
            strncpy(tmp_array, id_octet, 2); // 2 chars at a time

            int resp_byte = strtoul(tmp_array, NULL, 16); // Convert to hex byte
            memcpy((void*)&resp_uuid[resp_loc], &resp_byte, 1); // Copy end to first
            resp_loc--;
            id_octet+=2; // Finished with the 2 chars, advance
        }
        id_octet=strtok_r(NULL, "-", &tokptr); // Get next octet
    }

    // Data length
    *data_len = resp_size;

    // Pack the actual response
    memcpy(response, &resp_uuid, *data_len);

    sd_bus_error_free(&error);
    sd_bus_message_unref(m);

    return rc;
}
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;
}
// 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;
}
예제 #14
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);
    }
}
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;
}
예제 #16
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;
}
예제 #17
0
파일: bus-util.c 프로젝트: ChALkeR/systemd
int bus_test_polkit(
                sd_bus_message *call,
                int capability,
                const char *action,
                const char **details,
                uid_t good_user,
                bool *_challenge,
                sd_bus_error *e) {

        int r;

        assert(call);
        assert(action);

        /* Tests non-interactively! */

        r = check_good_user(call, good_user);
        if (r != 0)
                return r;

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

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

                r = sd_bus_message_new_method_call(
                                call->bus,
                                &request,
                                "org.freedesktop.PolicyKit1",
                                "/org/freedesktop/PolicyKit1/Authority",
                                "org.freedesktop.PolicyKit1.Authority",
                                "CheckAuthorization");
                if (r < 0)
                        return r;

                r = sd_bus_message_append(
                                request,
                                "(sa{sv})s",
                                "system-bus-name", 1, "name", "s", sender,
                                action);
                if (r < 0)
                        return r;

                r = sd_bus_message_open_container(request, 'a', "{ss}");
                if (r < 0)
                        return r;

                STRV_FOREACH_PAIR(k, v, details) {
                        r = sd_bus_message_append(request, "{ss}", *k, *v);
                        if (r < 0)
                                return r;
                }

                r = sd_bus_message_close_container(request);
                if (r < 0)
                        return r;

                r = sd_bus_message_append(request, "us", 0, NULL);
                if (r < 0)
                        return r;

                r = sd_bus_call(call->bus, request, 0, e, &reply);
                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;
                }
        }
예제 #18
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;
}
예제 #19
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;
}
예제 #20
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;
}
예제 #21
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;
}
예제 #22
0
파일: bus-util.c 프로젝트: shazj99/systemd
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;
}
예제 #23
0
int main(int argc, char *argv[]) {

    _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL;
    const sd_bus_error const_error = SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FILE_EXISTS, "const error");
    const sd_bus_error temporarily_const_error = {
        .name = SD_BUS_ERROR_ACCESS_DENIED,
        .message = "oh! no",
        ._need_free = -1
    };

    assert_se(!sd_bus_error_is_set(&error));
    assert_se(sd_bus_error_set(&error, SD_BUS_ERROR_NOT_SUPPORTED, "xxx") == -ENOTSUP);
    assert_se(streq(error.name, SD_BUS_ERROR_NOT_SUPPORTED));
    assert_se(streq(error.message, "xxx"));
    assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_NOT_SUPPORTED));
    assert_se(sd_bus_error_get_errno(&error) == ENOTSUP);
    assert_se(sd_bus_error_is_set(&error));
    sd_bus_error_free(&error);

    assert_se(!sd_bus_error_is_set(&error));
    assert_se(sd_bus_error_setf(&error, SD_BUS_ERROR_FILE_NOT_FOUND, "yyy %i", -1) == -ENOENT);
    assert_se(streq(error.name, SD_BUS_ERROR_FILE_NOT_FOUND));
    assert_se(streq(error.message, "yyy -1"));
    assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_FILE_NOT_FOUND));
    assert_se(sd_bus_error_get_errno(&error) == ENOENT);
    assert_se(sd_bus_error_is_set(&error));

    assert_se(!sd_bus_error_is_set(&second));
    assert_se(second._need_free == 0);
    assert_se(error._need_free > 0);
    assert_se(sd_bus_error_copy(&second, &error) == -ENOENT);
    assert_se(second._need_free > 0);
    assert_se(streq(error.name, second.name));
    assert_se(streq(error.message, second.message));
    assert_se(sd_bus_error_get_errno(&second) == ENOENT);
    assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_NOT_FOUND));
    assert_se(sd_bus_error_is_set(&second));

    sd_bus_error_free(&error);
    sd_bus_error_free(&second);

    assert_se(!sd_bus_error_is_set(&second));
    assert_se(const_error._need_free == 0);
    assert_se(sd_bus_error_copy(&second, &const_error) == -EEXIST);
    assert_se(second._need_free == 0);
    assert_se(streq(const_error.name, second.name));
    assert_se(streq(const_error.message, second.message));
    assert_se(sd_bus_error_get_errno(&second) == EEXIST);
    assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_EXISTS));
    assert_se(sd_bus_error_is_set(&second));
    sd_bus_error_free(&second);

    assert_se(!sd_bus_error_is_set(&second));
    assert_se(temporarily_const_error._need_free < 0);
    assert_se(sd_bus_error_copy(&second, &temporarily_const_error) == -EACCES);
    assert_se(second._need_free > 0);
    assert_se(streq(temporarily_const_error.name, second.name));
    assert_se(streq(temporarily_const_error.message, second.message));
    assert_se(sd_bus_error_get_errno(&second) == EACCES);
    assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_ACCESS_DENIED));
    assert_se(sd_bus_error_is_set(&second));

    assert_se(!sd_bus_error_is_set(&error));
    assert_se(sd_bus_error_set_const(&error, "System.Error.EUCLEAN", "Hallo") == -EUCLEAN);
    assert_se(streq(error.name, "System.Error.EUCLEAN"));
    assert_se(streq(error.message, "Hallo"));
    assert_se(sd_bus_error_has_name(&error, "System.Error.EUCLEAN"));
    assert_se(sd_bus_error_get_errno(&error) == EUCLEAN);
    assert_se(sd_bus_error_is_set(&error));
    sd_bus_error_free(&error);

    assert_se(!sd_bus_error_is_set(&error));
    assert_se(sd_bus_error_set_errno(&error, EBUSY) == -EBUSY);
    assert_se(streq(error.name, "System.Error.EBUSY"));
    assert_se(streq(error.message, strerror(EBUSY)));
    assert_se(sd_bus_error_has_name(&error, "System.Error.EBUSY"));
    assert_se(sd_bus_error_get_errno(&error) == EBUSY);
    assert_se(sd_bus_error_is_set(&error));
    sd_bus_error_free(&error);

    assert_se(!sd_bus_error_is_set(&error));
    assert_se(sd_bus_error_set_errnof(&error, EIO, "Waldi %c", 'X') == -EIO);
    assert_se(streq(error.name, SD_BUS_ERROR_IO_ERROR));
    assert_se(streq(error.message, "Waldi X"));
    assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_IO_ERROR));
    assert_se(sd_bus_error_get_errno(&error) == EIO);
    assert_se(sd_bus_error_is_set(&error));

    return 0;
}
예제 #24
0
//------------------------------------------------------------------------
// Takes FRU data, invokes Parser for each fru record area and updates
// Inventory
//------------------------------------------------------------------------
int ipmi_update_inventory(fru_area_vec_t & area_vec)
{
    // Generic error reporter
    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;

    // Response from sd bus calls
    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)
    {
        // Start fresh on each.
        sd_bus_error_free(&bus_error);
        sd_bus_message_unref(response);
        sd_bus_message_unref(fru_dict);

        // Constructor to allow further initializations and customization.
        rc = sd_bus_message_new_method_call((iter)->get_bus_type(),
                                            &fru_dict,
                                            (iter)->get_bus_name(),
                                            (iter)->get_obj_path(),
                                            (iter)->get_intf_name(),
                                            "update");
        if(rc < 0)
        {
            fprintf(stderr,"ERROR: creating a update method call for bus_name:[%s]\n",
                    (iter)->get_bus_name());
            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)->get_type(), (void *)(iter)->get_data(), (iter)->get_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((iter)->get_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, (iter)->get_fruid());
            break;
        }
        else if((iter)->is_bmc_fru())
        {
            // For FRUs that are accessible by HostBoot, host boot does all of
            // these.
            printf("SUCCESS: Updated:[%s_%d] successfully. Setting Valid bit\n",
                    (iter)->get_name(), (iter)->get_fruid());

            (iter)->set_valid(true);
        }
        else
        {
            printf("SUCCESS: Updated:[%s_%d] successfully\n",
                        (iter)->get_name(), (iter)->get_fruid());
        }
    } // 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);

    return rc;
}
예제 #25
0
/*
   This function communicates with the kernel to check whether or not it should
   allow the access.
   If the machine is in permissive mode it will return ok.  Audit messages will
   still be generated if the access would be denied in enforcing mode.
*/
int mac_selinux_generic_access_check(
                sd_bus_message *message,
                const char *path,
                const char *permission,
                sd_bus_error *error) {

        _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
        const char *tclass = NULL, *scon = NULL;
        struct audit_info audit_info = {};
        _cleanup_free_ char *cl = NULL;
        char *fcon = NULL;
        char **cmdline = NULL;
        int r = 0;

        assert(message);
        assert(permission);
        assert(error);

        r = access_init(error);
        if (r <= 0)
                return r;

        r = sd_bus_query_sender_creds(
                        message,
                        SD_BUS_CREDS_PID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|
                        SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_AUDIT_LOGIN_UID|
                        SD_BUS_CREDS_SELINUX_CONTEXT|
                        SD_BUS_CREDS_AUGMENT /* get more bits from /proc */,
                        &creds);
        if (r < 0)
                goto finish;

        /* The SELinux context is something we really should have
         * gotten directly from the message or sender, and not be an
         * augmented field. If it was augmented we cannot use it for
         * authorization, since this is racy and vulnerable. Let's add
         * an extra check, just in case, even though this really
         * shouldn't be possible. */
        assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_SELINUX_CONTEXT) == 0, -EPERM);

        r = sd_bus_creds_get_selinux_context(creds, &scon);
        if (r < 0)
                goto finish;

        if (path) {
                /* Get the file context of the unit file */

                r = getfilecon_raw(path, &fcon);
                if (r < 0) {
                        r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path);
                        goto finish;
                }

                tclass = "service";
        } else {
                r = getcon_raw(&fcon);
                if (r < 0) {
                        r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context.");
                        goto finish;
                }

                tclass = "system";
        }

        sd_bus_creds_get_cmdline(creds, &cmdline);
        cl = strv_join(cmdline, " ");

        audit_info.creds = creds;
        audit_info.path = path;
        audit_info.cmdline = cl;

        r = selinux_check_access(scon, fcon, tclass, permission, &audit_info);
        if (r < 0)
                r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access.");

        log_debug("SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %i", scon, fcon, tclass, permission, path, cl, r);

finish:
        freecon(fcon);

        if (r < 0 && security_getenforce() != 1) {
                sd_bus_error_free(error);
                r = 0;
        }

        return r;
}
예제 #26
0
/*
   This function communicates with the kernel to check whether or not it should
   allow the access.
   If the machine is in permissive mode it will return ok.  Audit messages will
   still be generated if the access would be denied in enforcing mode.
*/
int mac_selinux_generic_access_check(
                sd_bus_message *message,
                bool system,
                const char *path,
                const char *permission,
                sd_bus_error *error) {

#ifdef HAVE_SELINUX
        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
        const char *tclass = NULL, *scon = NULL;
        struct audit_info audit_info = {};
        _cleanup_free_ char *cl = NULL;
        security_context_t fcon = NULL;
        char **cmdline = NULL;
        int r = 0;

        assert(message);
        assert(permission);
        assert(error);

        if (!mac_selinux_use())
                return 0;

        r = mac_selinux_access_init(error);
        if (r < 0)
                return r;

        r = sd_bus_query_sender_creds(
                        message,
                        SD_BUS_CREDS_PID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|
                        SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_AUDIT_LOGIN_UID|
                        SD_BUS_CREDS_SELINUX_CONTEXT|
                        SD_BUS_CREDS_AUGMENT /* get more bits from /proc */,
                        &creds);
        if (r < 0)
                goto finish;

        r = sd_bus_creds_get_selinux_context(creds, &scon);
        if (r < 0)
                goto finish;

        tclass = "service";

        if (path && !system) {
                /* Get the file context of the unit file */

                r = getfilecon_raw(path, &fcon);
                if (r < 0) {
                        r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path);
                        goto finish;
                }
        } else {
                r = getcon_raw(&fcon);
                if (r < 0) {
                        r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context.");
                        goto finish;
                }
                if (system)
                        tclass = "system";
        }

        sd_bus_creds_get_cmdline(creds, &cmdline);
        cl = strv_join(cmdline, " ");

        audit_info.creds = creds;
        audit_info.path = path;
        audit_info.cmdline = cl;

        r = selinux_check_access(scon, fcon, tclass, permission, &audit_info);
        if (r < 0)
                r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access.");

        log_debug("SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %i", scon, fcon, tclass, permission, path, cl, r);

finish:
        freecon(fcon);

        if (r < 0 && security_getenforce() != 1) {
                sd_bus_error_free(error);
                r = 0;
        }

        return r;
#else
        return 0;
#endif
}
예제 #27
0
static int send_ipmi_message(unsigned char seq, unsigned char netfn, unsigned char cmd, unsigned char *buf, unsigned char len) {

    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_message *reply = NULL, *m=NULL;


    const char *path;
    int r, pty;


    r = sd_bus_message_new_method_call(bus,&m,DBUS_NAME,OBJ_NAME,DBUS_NAME,"sendMessage");
    if (r < 0) {
        fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
        return -1;
    }


    // Responses in IPMI require a bit set.  So there ya go...
    netfn |= 0x04;


    // Add the bytes needed for the methods to be called
    r = sd_bus_message_append(m, "yyy", seq, netfn, cmd);
    if (r < 0) {
        fprintf(stderr, "Failed add the netfn and others : %s\n", strerror(-r));
        return -1;
    }
   
    r = sd_bus_message_append_array(m, 'y', buf, len);
    if (r < 0) {
        fprintf(stderr, "Failed to add the string of response bytes: %s\n", strerror(-r));
        return -1;
    }



    // Call the IPMI responder on the bus so the message can be sent to the CEC
    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0) {
        fprintf(stderr, "Failed to call the method: %s", strerror(-r));
        return -1;
    }

    r = sd_bus_message_read(reply, "x", &pty);
#ifdef __IPMI_DEBUG__
    printf("RC from the ipmi dbus method :%d \n", pty);
#endif    
    if (r < 0) {
       fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));

    }


    sd_bus_error_free(&error);
    sd_bus_message_unref(m);


#ifdef __IPMI_DEBUG__
    printf("%d : %s\n", __LINE__, __PRETTY_FUNCTION__ );
#endif    
    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;

}
예제 #28
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);
    }
}
예제 #29
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;
}
예제 #30
0
ipmi_ret_t ipmi_app_set_watchdog(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)
{
    const char  *busname = "org.openbmc.watchdog.Host";
    const char  *objname = "/org/openbmc/watchdog/host0";
    const char  *iface = "org.openbmc.Watchdog";
    sd_bus_message *reply = NULL, *m = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int r = 0;

    set_wd_data_t *reqptr = (set_wd_data_t*) request;
    uint16_t timer = 0;
    uint32_t timer_ms = 0;
    // Status code.
    ipmi_ret_t rc = IPMI_CC_OK;

    *data_len = 0;

    // Get number of 100ms intervals
    timer = (((uint16_t)reqptr->ms) << 8) + reqptr->ls;
    // Get timer value in ms
    timer_ms = timer * 100;

    printf("WATCHDOG SET Timer:[0x%X] 100ms intervals\n",timer);

    // Set watchdog timer
    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"set");
    if (r < 0) {
        fprintf(stderr, "Failed to add the set method object: %s\n", strerror(-r));
        return -1;
    }
    r = sd_bus_message_append(m, "i", timer_ms);
    if (r < 0) {
        fprintf(stderr, "Failed to add timer value: %s\n", strerror(-r));
        return -1;
    }
    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0) {
        fprintf(stderr, "Failed to call the set method: %s\n", strerror(-r));
        return -1;
    }

    // Stop the current watchdog if any
    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"stop");
    if (r < 0) {
        fprintf(stderr, "Failed to add the start method object: %s\n", strerror(-r));
        return -1;
    }
    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0) {
        fprintf(stderr, "Failed to call the start method: %s\n", strerror(-r));
        return -1;
    }

    // Start the watchdog if requested
    if (reqptr->t_use & 0x40)
    {
        r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"start");
        if (r < 0) {
            fprintf(stderr, "Failed to add the start method object: %s\n", strerror(-r));
            return -1;
        }
        r = sd_bus_call(bus, m, 0, &error, &reply);
        if (r < 0) {
            fprintf(stderr, "Failed to call the start method: %s\n", strerror(-r));
            return -1;
        }
    }

    sd_bus_error_free(&error);
    sd_bus_message_unref(m);

    return rc;
}