static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) { Context *c = userdata; const char *name; int interactive; char *h; int r; assert(m); assert(c); r = sd_bus_message_read(m, "sb", &name, &interactive); if (r < 0) return r; if (isempty(name)) name = c->data[PROP_STATIC_HOSTNAME]; if (isempty(name)) name = "localhost"; if (!hostname_is_valid(name, false)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", name); if (streq_ptr(name, c->data[PROP_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-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 */ h = strdup(name); if (!h) return -ENOMEM; free(c->data[PROP_HOSTNAME]); c->data[PROP_HOSTNAME] = h; 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: %s", strerror(-r)); } log_info("Changed host name to '%s'", strna(c->data[PROP_HOSTNAME])); (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "Hostname", NULL); return sd_bus_reply_method_return(m, NULL); }
static int set_hostname(sd_bus *bus, char **args, unsigned n) { _cleanup_free_ char *h = NULL; char *hostname = args[1]; int r; assert(args); assert(n == 2); if (!arg_pretty && !arg_static && !arg_transient) arg_pretty = arg_static = arg_transient = true; if (arg_pretty) { const char *p; /* If the passed hostname is already valid, then * assume the user doesn't know anything about pretty * hostnames, so let's unset the pretty hostname, and * just set the passed hostname as static/dynamic * hostname. */ if (arg_static && hostname_is_valid(hostname, true)) { p = ""; /* maybe get rid of trailing dot */ hostname = hostname_cleanup(hostname); } else { p = h = strdup(hostname); if (!p) return log_oom(); hostname_cleanup(hostname); } r = set_simple_string(bus, "SetPrettyHostname", p); if (r < 0) return r; } if (arg_static) { r = set_simple_string(bus, "SetStaticHostname", hostname); if (r < 0) return r; } if (arg_transient) { r = set_simple_string(bus, "SetHostname", hostname); if (r < 0) return r; } return 0; }
static int set_hostname(int argc, char **argv, void *userdata) { _cleanup_free_ char *h = NULL; const char *hostname = argv[1]; sd_bus *bus = userdata; int r; if (!arg_pretty && !arg_static && !arg_transient) arg_pretty = arg_static = arg_transient = true; if (arg_pretty) { const char *p; /* If the passed hostname is already valid, then assume the user doesn't know anything about pretty * hostnames, so let's unset the pretty hostname, and just set the passed hostname as static/dynamic * hostname. */ if (arg_static && hostname_is_valid(hostname, true)) p = ""; /* No pretty hostname (as it is redundant), just a static one */ else p = hostname; /* Use the passed name as pretty hostname */ r = set_simple_string(bus, "SetPrettyHostname", p); if (r < 0) return r; /* Now that we set the pretty hostname, let's clean up the parameter and use that as static * hostname. If the hostname was already valid as static hostname, this will only chop off the trailing * dot if there is one. If it was not valid, then it will be made fully valid by truncating, dropping * multiple dots, and dropping weird chars. Note that we clean the name up only if we also are * supposed to set the pretty name. If the pretty name is not being set we assume the user knows what * he does and pass the name as-is. */ h = strdup(hostname); if (!h) return log_oom(); hostname = hostname_cleanup(h); /* Use the cleaned up name as static hostname */ } if (arg_static) { r = set_simple_string(bus, "SetStaticHostname", hostname); if (r < 0) return r; } if (arg_transient) { r = set_simple_string(bus, "SetHostname", hostname); if (r < 0) return r; } return 0; }
static int dkr_pull_job_on_header(PullJob *j, const char *header, size_t sz) { _cleanup_free_ char *registry = NULL; char *token, *digest; DkrPull *i; int r; assert(j); assert(j->userdata); i = j->userdata; r = curl_header_strdup(header, sz, HEADER_TOKEN, &token); if (r < 0) return log_oom(); if (r > 0) { free(i->response_token); i->response_token = token; return 0; } r = curl_header_strdup(header, sz, HEADER_DIGEST, &digest); if (r < 0) return log_oom(); if (r > 0) { free(i->response_digest); i->response_digest = digest; return 0; } r = curl_header_strdup(header, sz, HEADER_REGISTRY, ®istry); if (r < 0) return log_oom(); if (r > 0) { char **l, **k; l = strv_split(registry, ","); if (!l) return log_oom(); STRV_FOREACH(k, l) { if (!hostname_is_valid(*k)) { log_error("Registry hostname is not valid."); strv_free(l); return -EBADMSG; } } strv_free(i->response_registries); i->response_registries = l; }
static int prompt_hostname(void) { int r; if (arg_hostname) return 0; if (!arg_prompt_hostname) return 0; print_welcome(); putchar('\n'); for (;;) { _cleanup_free_ char *h = NULL; r = ask_string(&h, "%s Please enter hostname for new system (empty to skip): ", draw_special_char(DRAW_TRIANGULAR_BULLET)); if (r < 0) { log_error("Failed to query hostname: %s", strerror(-r)); return r; } if (isempty(h)) { log_warning("No hostname entered, skipping."); break; } if (!hostname_is_valid(h)) { log_error("Specified hostname invalid."); continue; } arg_hostname = h; h = NULL; break; } return 0; }
static int prompt_hostname(void) { int r; if (arg_hostname) return 0; if (!arg_prompt_hostname) return 0; print_welcome(); putchar('\n'); for (;;) { _cleanup_free_ char *h = NULL; r = ask_string(&h, "%s Please enter hostname for new system (empty to skip): ", draw_special_char(DRAW_TRIANGULAR_BULLET)); if (r < 0) return log_error_errno(r, "Failed to query hostname: %m"); if (isempty(h)) { log_warning("No hostname entered, skipping."); break; } if (!hostname_is_valid(h, true)) { log_error("Specified hostname invalid."); continue; } /* Get rid of the trailing dot that we allow, but don't want to see */ arg_hostname = hostname_cleanup(h); h = NULL; break; } return 0; }
int read_etc_hostname_stream(FILE *f, char **ret) { int r; assert(f); assert(ret); for (;;) { _cleanup_free_ char *line = NULL; char *p; r = read_line(f, LONG_LINE_MAX, &line); if (r < 0) return r; if (r == 0) /* EOF without any hostname? the file is empty, let's treat that exactly like no file at all: ENOENT */ return -ENOENT; p = strstrip(line); /* File may have empty lines or comments, ignore them */ if (!IN_SET(*p, '\0', '#')) { char *copy; hostname_cleanup(p); /* normalize the hostname */ if (!hostname_is_valid(p, true)) /* check that the hostname we return is valid */ return -EBADMSG; copy = strdup(p); if (!copy) return -ENOMEM; *ret = copy; return 0; } } }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_ROOT, ARG_LOCALE, ARG_LOCALE_MESSAGES, ARG_TIMEZONE, ARG_HOSTNAME, ARG_MACHINE_ID, ARG_ROOT_PASSWORD, ARG_ROOT_PASSWORD_FILE, ARG_PROMPT, ARG_PROMPT_LOCALE, ARG_PROMPT_TIMEZONE, ARG_PROMPT_HOSTNAME, ARG_PROMPT_ROOT_PASSWORD, ARG_COPY, ARG_COPY_LOCALE, ARG_COPY_TIMEZONE, ARG_COPY_ROOT_PASSWORD, ARG_SETUP_MACHINE_ID, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "root", required_argument, NULL, ARG_ROOT }, { "locale", required_argument, NULL, ARG_LOCALE }, { "locale-messages", required_argument, NULL, ARG_LOCALE_MESSAGES }, { "timezone", required_argument, NULL, ARG_TIMEZONE }, { "hostname", required_argument, NULL, ARG_HOSTNAME }, { "machine-id", required_argument, NULL, ARG_MACHINE_ID }, { "root-password", required_argument, NULL, ARG_ROOT_PASSWORD }, { "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE }, { "prompt", no_argument, NULL, ARG_PROMPT }, { "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE }, { "prompt-timezone", no_argument, NULL, ARG_PROMPT_TIMEZONE }, { "prompt-hostname", no_argument, NULL, ARG_PROMPT_HOSTNAME }, { "prompt-root-password", no_argument, NULL, ARG_PROMPT_ROOT_PASSWORD }, { "copy", no_argument, NULL, ARG_COPY }, { "copy-locale", no_argument, NULL, ARG_COPY_LOCALE }, { "copy-timezone", no_argument, NULL, ARG_COPY_TIMEZONE }, { "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD }, { "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID }, {} }; int r, c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case ARG_ROOT: free(arg_root); arg_root = path_make_absolute_cwd(optarg); if (!arg_root) return log_oom(); path_kill_slashes(arg_root); if (path_equal(arg_root, "/")) arg_root = mfree(arg_root); break; case ARG_LOCALE: if (!locale_is_valid(optarg)) { log_error("Locale %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_locale, optarg); if (r < 0) return log_oom(); break; case ARG_LOCALE_MESSAGES: if (!locale_is_valid(optarg)) { log_error("Locale %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_locale_messages, optarg); if (r < 0) return log_oom(); break; case ARG_TIMEZONE: if (!timezone_is_valid(optarg)) { log_error("Timezone %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_timezone, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD: r = free_and_strdup(&arg_root_password, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD_FILE: arg_root_password = mfree(arg_root_password); r = read_one_line_file(optarg, &arg_root_password); if (r < 0) return log_error_errno(r, "Failed to read %s: %m", optarg); break; case ARG_HOSTNAME: if (!hostname_is_valid(optarg, true)) { log_error("Host name %s is not valid.", optarg); return -EINVAL; } hostname_cleanup(optarg); r = free_and_strdup(&arg_hostname, optarg); if (r < 0) return log_oom(); break; case ARG_MACHINE_ID: if (sd_id128_from_string(optarg, &arg_machine_id) < 0) { log_error("Failed to parse machine id %s.", optarg); return -EINVAL; } break; case ARG_PROMPT: arg_prompt_locale = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true; break; case ARG_PROMPT_LOCALE: arg_prompt_locale = true; break; case ARG_PROMPT_TIMEZONE: arg_prompt_timezone = true; break; case ARG_PROMPT_HOSTNAME: arg_prompt_hostname = true; break; case ARG_PROMPT_ROOT_PASSWORD: arg_prompt_root_password = true; break; case ARG_COPY: arg_copy_locale = arg_copy_timezone = arg_copy_root_password = true; break; case ARG_COPY_LOCALE: arg_copy_locale = true; break; case ARG_COPY_TIMEZONE: arg_copy_timezone = true; break; case ARG_COPY_ROOT_PASSWORD: arg_copy_root_password = true; break; case ARG_SETUP_MACHINE_ID: r = sd_id128_randomize(&arg_machine_id); if (r < 0) return log_error_errno(r, "Failed to generate randomized machine ID: %m"); break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
static void test_hostname_is_valid(void) { assert_se(hostname_is_valid("foobar", false)); assert_se(hostname_is_valid("foobar.com", false)); assert_se(!hostname_is_valid("foobar.com.", false)); assert_se(hostname_is_valid("fooBAR", false)); assert_se(hostname_is_valid("fooBAR.com", false)); assert_se(!hostname_is_valid("fooBAR.", false)); assert_se(!hostname_is_valid("fooBAR.com.", false)); assert_se(!hostname_is_valid("fööbar", false)); assert_se(!hostname_is_valid("", false)); assert_se(!hostname_is_valid(".", false)); assert_se(!hostname_is_valid("..", false)); assert_se(!hostname_is_valid("foobar.", false)); assert_se(!hostname_is_valid(".foobar", false)); assert_se(!hostname_is_valid("foo..bar", false)); assert_se(!hostname_is_valid("foo.bar..", false)); assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", false)); assert_se(hostname_is_valid("foobar", true)); assert_se(hostname_is_valid("foobar.com", true)); assert_se(hostname_is_valid("foobar.com.", true)); assert_se(hostname_is_valid("fooBAR", true)); assert_se(hostname_is_valid("fooBAR.com", true)); assert_se(!hostname_is_valid("fooBAR.", true)); assert_se(hostname_is_valid("fooBAR.com.", true)); assert_se(!hostname_is_valid("fööbar", true)); assert_se(!hostname_is_valid("", true)); assert_se(!hostname_is_valid(".", true)); assert_se(!hostname_is_valid("..", true)); assert_se(!hostname_is_valid("foobar.", true)); assert_se(!hostname_is_valid(".foobar", true)); assert_se(!hostname_is_valid("foo..bar", true)); assert_se(!hostname_is_valid("foo.bar..", true)); assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", true)); }
static void test_hostname_is_valid(void) { assert_se(hostname_is_valid("foobar", false)); assert_se(hostname_is_valid("foobar.com", false)); assert_se(!hostname_is_valid("foobar.com.", false)); assert_se(hostname_is_valid("fooBAR", false)); assert_se(hostname_is_valid("fooBAR.com", false)); assert_se(!hostname_is_valid("fooBAR.", false)); assert_se(!hostname_is_valid("fooBAR.com.", false)); assert_se(!hostname_is_valid("fööbar", false)); assert_se(!hostname_is_valid("", false)); assert_se(!hostname_is_valid(".", false)); assert_se(!hostname_is_valid("..", false)); assert_se(!hostname_is_valid("foobar.", false)); assert_se(!hostname_is_valid(".foobar", false)); assert_se(!hostname_is_valid("foo..bar", false)); assert_se(!hostname_is_valid("foo.bar..", false)); assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", false)); assert_se(!hostname_is_valid("au-xph5-rvgrdsb5hcxc-47et3a5vvkrc-server-wyoz4elpdpe3.openstack.local", false)); assert_se(hostname_is_valid("foobar", true)); assert_se(hostname_is_valid("foobar.com", true)); assert_se(hostname_is_valid("foobar.com.", true)); assert_se(hostname_is_valid("fooBAR", true)); assert_se(hostname_is_valid("fooBAR.com", true)); assert_se(!hostname_is_valid("fooBAR.", true)); assert_se(hostname_is_valid("fooBAR.com.", true)); assert_se(!hostname_is_valid("fööbar", true)); assert_se(!hostname_is_valid("", true)); assert_se(!hostname_is_valid(".", true)); assert_se(!hostname_is_valid("..", true)); assert_se(!hostname_is_valid("foobar.", true)); assert_se(!hostname_is_valid(".foobar", true)); assert_se(!hostname_is_valid("foo..bar", true)); assert_se(!hostname_is_valid("foo.bar..", true)); assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", true)); }