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; }
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); }
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; }
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; }
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); }
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; }