Ejemplo n.º 1
0
int config_parse_hostname(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        char **s = data;

        assert(rvalue);
        assert(s);

        if (!hostname_is_valid(rvalue, false)) {
                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid hostname, ignoring: %s", rvalue);
                return 0;
        }

        if (free_and_strdup(s, empty_to_null(rvalue)) < 0)
                return log_oom();

        return 0;
}
Ejemplo n.º 2
0
static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) {
        Context *c = userdata;
        const char *name;
        int interactive;
        int r;

        assert(m);
        assert(c);

        r = sd_bus_message_read(m, "sb", &name, &interactive);
        if (r < 0)
                return r;

        name = empty_to_null(name);

        if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME]))
                return sd_bus_reply_method_return(m, NULL);

        if (!isempty(name) && !hostname_is_valid(name, false))
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name);

        r = bus_verify_polkit_async(
                        m,
                        CAP_SYS_ADMIN,
                        "org.freedesktop.hostname1.set-static-hostname",
                        NULL,
                        interactive,
                        UID_INVALID,
                        &c->polkit_registry,
                        error);
        if (r < 0)
                return r;
        if (r == 0)
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */

        r = free_and_strdup(&c->data[PROP_STATIC_HOSTNAME], name);
        if (r < 0)
                return r;

        r = context_update_kernel_hostname(c);
        if (r < 0) {
                log_error_errno(r, "Failed to set host name: %m");
                return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %m");
        }

        r = context_write_data_static_hostname(c);
        if (r < 0) {
                log_error_errno(r, "Failed to write static host name: %m");
                return sd_bus_error_set_errnof(error, r, "Failed to set static hostname: %m");
        }

        log_info("Changed static host name to '%s'", strna(c->data[PROP_STATIC_HOSTNAME]));

        (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "StaticHostname", NULL);

        return sd_bus_reply_method_return(m, NULL);
}
Ejemplo n.º 3
0
static int locale_read_data(Context *c) {
        int r;

        context_free_locale(c);

        r = parse_env_file("/etc/locale.conf", NEWLINE,
                           "LANG",              &c->locale[VARIABLE_LANG],
                           "LANGUAGE",          &c->locale[VARIABLE_LANGUAGE],
                           "LC_CTYPE",          &c->locale[VARIABLE_LC_CTYPE],
                           "LC_NUMERIC",        &c->locale[VARIABLE_LC_NUMERIC],
                           "LC_TIME",           &c->locale[VARIABLE_LC_TIME],
                           "LC_COLLATE",        &c->locale[VARIABLE_LC_COLLATE],
                           "LC_MONETARY",       &c->locale[VARIABLE_LC_MONETARY],
                           "LC_MESSAGES",       &c->locale[VARIABLE_LC_MESSAGES],
                           "LC_PAPER",          &c->locale[VARIABLE_LC_PAPER],
                           "LC_NAME",           &c->locale[VARIABLE_LC_NAME],
                           "LC_ADDRESS",        &c->locale[VARIABLE_LC_ADDRESS],
                           "LC_TELEPHONE",      &c->locale[VARIABLE_LC_TELEPHONE],
                           "LC_MEASUREMENT",    &c->locale[VARIABLE_LC_MEASUREMENT],
                           "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION],
                           NULL);

        if (r == -ENOENT) {
                int p;

                /* Fill in what we got passed from systemd. */
                for (p = 0; p < _VARIABLE_LC_MAX; p++) {
                        const char *name;

                        name = locale_variable_to_string(p);
                        assert(name);

                        r = free_and_strdup(&c->locale[p], empty_to_null(getenv(name)));
                        if (r < 0)
                                return r;
                }

                r = 0;
        }

        locale_simplify(c);
        return r;
}
Ejemplo n.º 4
0
int locale_read_data(Context *c, sd_bus_message *m) {
        struct stat st;
        int r;

        /* Do not try to re-read the file within single bus operation. */
        if (m) {
                if (m == c->locale_cache)
                        return 0;

                sd_bus_message_unref(c->locale_cache);
                c->locale_cache = sd_bus_message_ref(m);
        }

        r = stat("/etc/locale.conf", &st);
        if (r < 0 && errno != ENOENT)
                return -errno;

        if (r >= 0) {
                usec_t t;

                /* If mtime is not changed, then we do not need to re-read the file. */
                t = timespec_load(&st.st_mtim);
                if (c->locale_mtime != USEC_INFINITY && t == c->locale_mtime)
                        return 0;

                c->locale_mtime = t;
                context_free_locale(c);

                r = parse_env_file(NULL, "/etc/locale.conf", NEWLINE,
                                   "LANG",              &c->locale[VARIABLE_LANG],
                                   "LANGUAGE",          &c->locale[VARIABLE_LANGUAGE],
                                   "LC_CTYPE",          &c->locale[VARIABLE_LC_CTYPE],
                                   "LC_NUMERIC",        &c->locale[VARIABLE_LC_NUMERIC],
                                   "LC_TIME",           &c->locale[VARIABLE_LC_TIME],
                                   "LC_COLLATE",        &c->locale[VARIABLE_LC_COLLATE],
                                   "LC_MONETARY",       &c->locale[VARIABLE_LC_MONETARY],
                                   "LC_MESSAGES",       &c->locale[VARIABLE_LC_MESSAGES],
                                   "LC_PAPER",          &c->locale[VARIABLE_LC_PAPER],
                                   "LC_NAME",           &c->locale[VARIABLE_LC_NAME],
                                   "LC_ADDRESS",        &c->locale[VARIABLE_LC_ADDRESS],
                                   "LC_TELEPHONE",      &c->locale[VARIABLE_LC_TELEPHONE],
                                   "LC_MEASUREMENT",    &c->locale[VARIABLE_LC_MEASUREMENT],
                                   "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION],
                                   NULL);
                if (r < 0)
                        return r;
        } else {
                int p;

                c->locale_mtime = USEC_INFINITY;
                context_free_locale(c);

                /* Fill in what we got passed from systemd. */
                for (p = 0; p < _VARIABLE_LC_MAX; p++) {
                        const char *name;

                        name = locale_variable_to_string(p);
                        assert(name);

                        r = free_and_strdup(&c->locale[p], empty_to_null(getenv(name)));
                        if (r < 0)
                                return r;
                }
        }

        locale_simplify(c->locale);
        return 0;
}
Ejemplo n.º 5
0
static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_message_handler_t cb, sd_bus_error *error) {
        int interactive;
        const char *name;
        int r;

        assert(c);
        assert(m);

        r = sd_bus_message_read(m, "sb", &name, &interactive);
        if (r < 0)
                return r;

        name = empty_to_null(name);

        if (streq_ptr(name, c->data[prop]))
                return sd_bus_reply_method_return(m, NULL);

        /* Since the pretty hostname should always be changed at the
         * same time as the static one, use the same policy action for
         * both... */

        r = bus_verify_polkit_async(
                        m,
                        CAP_SYS_ADMIN,
                        prop == PROP_PRETTY_HOSTNAME ? "org.freedesktop.hostname1.set-static-hostname" : "org.freedesktop.hostname1.set-machine-info",
                        NULL,
                        interactive,
                        UID_INVALID,
                        &c->polkit_registry,
                        error);
        if (r < 0)
                return r;
        if (r == 0)
                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */

        if (isempty(name))
                c->data[prop] = mfree(c->data[prop]);
        else {
                char *h;

                /* The icon name might ultimately be used as file
                 * name, so better be safe than sorry */

                if (prop == PROP_ICON_NAME && !filename_is_valid(name))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name);
                if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name);
                if (prop == PROP_CHASSIS && !valid_chassis(name))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name);
                if (prop == PROP_DEPLOYMENT && !valid_deployment(name))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid deployment '%s'", name);
                if (prop == PROP_LOCATION && string_has_cc(name, NULL))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid location '%s'", name);

                h = strdup(name);
                if (!h)
                        return -ENOMEM;

                free(c->data[prop]);
                c->data[prop] = h;
        }

        r = context_write_data_machine_info(c);
        if (r < 0) {
                log_error_errno(r, "Failed to write machine info: %m");
                return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %m");
        }

        log_info("Changed %s to '%s'",
                 prop == PROP_PRETTY_HOSTNAME ? "pretty host name" :
                 prop == PROP_DEPLOYMENT ? "deployment" :
                 prop == PROP_LOCATION ? "location" :
                 prop == PROP_CHASSIS ? "chassis" : "icon name", strna(c->data[prop]));

        (void) sd_bus_emit_properties_changed(
                        sd_bus_message_get_bus(m),
                        "/org/freedesktop/hostname1",
                        "org.freedesktop.hostname1",
                        prop == PROP_PRETTY_HOSTNAME ? "PrettyHostname" :
                        prop == PROP_DEPLOYMENT ? "Deployment" :
                        prop == PROP_LOCATION ? "Location" :
                        prop == PROP_CHASSIS ? "Chassis" : "IconName" , NULL);

        return sd_bus_reply_method_return(m, NULL);
}
Ejemplo n.º 6
0
static int bus_scope_set_transient_property(
                Scope *s,
                const char *name,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        int r;

        assert(s);
        assert(name);
        assert(message);

        flags |= UNIT_PRIVATE;

        if (streq(name, "TimeoutStopUSec"))
                return bus_set_transient_usec(UNIT(s), name, &s->timeout_stop_usec, message, flags, error);

        if (streq(name, "PIDs")) {
                _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
                unsigned n = 0;

                r = sd_bus_message_enter_container(message, 'a', "u");
                if (r < 0)
                        return r;

                for (;;) {
                        uint32_t upid;
                        pid_t pid;

                        r = sd_bus_message_read(message, "u", &upid);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                break;

                        if (upid == 0) {
                                if (!creds) {
                                        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
                                        if (r < 0)
                                                return r;
                                }

                                r = sd_bus_creds_get_pid(creds, &pid);
                                if (r < 0)
                                        return r;
                        } else
                                pid = (uid_t) upid;

                        r = unit_pid_attachable(UNIT(s), pid, error);
                        if (r < 0)
                                return r;

                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                r = unit_watch_pid(UNIT(s), pid);
                                if (r < 0 && r != -EEXIST)
                                        return r;
                        }

                        n++;
                }

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

                if (n <= 0)
                        return -EINVAL;

                return 1;

        } else if (streq(name, "Controller")) {
                const char *controller;

                /* We can't support direct connections with this, as direct connections know no service or unique name
                 * concept, but the Controller field stores exactly that. */
                if (sd_bus_message_get_bus(message) != UNIT(s)->manager->api_bus)
                        return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Sorry, Controller= logic only supported via the bus.");

                r = sd_bus_message_read(message, "s", &controller);
                if (r < 0)
                        return r;

                if (!isempty(controller) && !service_name_is_valid(controller))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);

                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                        r = free_and_strdup(&s->controller, empty_to_null(controller));
                        if (r < 0)
                                return r;
                }

                return 1;
        }

        return 0;
}