| File: | build-scan/../src/firstboot/firstboot.c | 
| Warning: | line 478, column 24 Null pointer passed to 1st parameter expecting 'nonnull' | 
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
| 2 | ||||
| 3 | #include <fcntl.h> | |||
| 4 | #include <getopt.h> | |||
| 5 | #include <unistd.h> | |||
| 6 | ||||
| 7 | #ifdef HAVE_CRYPT_H1 | |||
| 8 | /* libxcrypt is a replacement for glibc's libcrypt, and libcrypt might be | |||
| 9 | * removed from glibc at some point. As part of the removal, defines for | |||
| 10 | * crypt(3) are dropped from unistd.h, and we must include crypt.h instead. | |||
| 11 | * | |||
| 12 | * Newer versions of glibc (v2.0+) already ship crypt.h with a definition | |||
| 13 | * of crypt(3) as well, so we simply include it if it is present. MariaDB, | |||
| 14 | * MySQL, PostgreSQL, Perl and some other wide-spread packages do it the | |||
| 15 | * same way since ages without any problems. | |||
| 16 | */ | |||
| 17 | # include <crypt.h> | |||
| 18 | #endif | |||
| 19 | ||||
| 20 | #include "sd-id128.h" | |||
| 21 | ||||
| 22 | #include "alloc-util.h" | |||
| 23 | #include "ask-password-api.h" | |||
| 24 | #include "copy.h" | |||
| 25 | #include "fd-util.h" | |||
| 26 | #include "fileio.h" | |||
| 27 | #include "fs-util.h" | |||
| 28 | #include "hostname-util.h" | |||
| 29 | #include "locale-util.h" | |||
| 30 | #include "mkdir.h" | |||
| 31 | #include "os-util.h" | |||
| 32 | #include "parse-util.h" | |||
| 33 | #include "path-util.h" | |||
| 34 | #include "proc-cmdline.h" | |||
| 35 | #include "random-util.h" | |||
| 36 | #include "string-util.h" | |||
| 37 | #include "strv.h" | |||
| 38 | #include "terminal-util.h" | |||
| 39 | #include "time-util.h" | |||
| 40 | #include "umask-util.h" | |||
| 41 | #include "user-util.h" | |||
| 42 | ||||
| 43 | static char *arg_root = NULL((void*)0); | |||
| 44 | static char *arg_locale = NULL((void*)0); /* $LANG */ | |||
| 45 | static char *arg_keymap = NULL((void*)0); | |||
| 46 | static char *arg_locale_messages = NULL((void*)0); /* $LC_MESSAGES */ | |||
| 47 | static char *arg_timezone = NULL((void*)0); | |||
| 48 | static char *arg_hostname = NULL((void*)0); | |||
| 49 | static sd_id128_t arg_machine_id = {}; | |||
| 50 | static char *arg_root_password = NULL((void*)0); | |||
| 51 | static bool_Bool arg_prompt_locale = false0; | |||
| 52 | static bool_Bool arg_prompt_keymap = false0; | |||
| 53 | static bool_Bool arg_prompt_timezone = false0; | |||
| 54 | static bool_Bool arg_prompt_hostname = false0; | |||
| 55 | static bool_Bool arg_prompt_root_password = false0; | |||
| 56 | static bool_Bool arg_copy_locale = false0; | |||
| 57 | static bool_Bool arg_copy_keymap = false0; | |||
| 58 | static bool_Bool arg_copy_timezone = false0; | |||
| 59 | static bool_Bool arg_copy_root_password = false0; | |||
| 60 | ||||
| 61 | static bool_Bool press_any_key(void) { | |||
| 62 | char k = 0; | |||
| 63 | bool_Bool need_nl = true1; | |||
| 64 | ||||
| 65 | printf("-- Press any key to proceed --"); | |||
| 66 | fflush(stdoutstdout); | |||
| 67 | ||||
| 68 | (void) read_one_char(stdinstdin, &k, USEC_INFINITY((usec_t) -1), &need_nl); | |||
| 69 | ||||
| 70 | if (need_nl) | |||
| 71 | putchar('\n'); | |||
| 72 | ||||
| 73 | return k != 'q'; | |||
| 74 | } | |||
| 75 | ||||
| 76 | static void print_welcome(void) { | |||
| 77 | _cleanup_free___attribute__((cleanup(freep))) char *pretty_name = NULL((void*)0); | |||
| 78 | static bool_Bool done = false0; | |||
| 79 | int r; | |||
| 80 | ||||
| 81 | if (done) | |||
| 82 | return; | |||
| 83 | ||||
| 84 | r = parse_os_release(arg_root, "PRETTY_NAME", &pretty_name, NULL((void*)0)); | |||
| 85 | if (r < 0) | |||
| 86 | log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,({ int _level = ((r == -2 ? 7 : 4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 87, __func__, "Failed to read os-release file, ignoring: %m" ) : -abs(_e); }) | |||
| 87 | "Failed to read os-release file, ignoring: %m")({ int _level = ((r == -2 ? 7 : 4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 87, __func__, "Failed to read os-release file, ignoring: %m" ) : -abs(_e); }); | |||
| 88 | ||||
| 89 | printf("\nWelcome to your new installation of %s!\nPlease configure a few basic system settings:\n\n", | |||
| 90 | isempty(pretty_name) ? "Linux" : pretty_name); | |||
| 91 | ||||
| 92 | press_any_key(); | |||
| 93 | ||||
| 94 | done = true1; | |||
| 95 | } | |||
| 96 | ||||
| 97 | static int show_menu(char **x, unsigned n_columns, unsigned width, unsigned percentage) { | |||
| 98 | unsigned break_lines, break_modulo; | |||
| 99 | size_t n, per_column, i, j; | |||
| 100 | ||||
| 101 | assert(n_columns > 0)do { if ((__builtin_expect(!!(!(n_columns > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n_columns > 0"), "../src/firstboot/firstboot.c" , 101, __PRETTY_FUNCTION__); } while (0); | |||
| 102 | ||||
| 103 | n = strv_length(x); | |||
| 104 | per_column = DIV_ROUND_UP(n, n_columns)({ const typeof((n)) __unique_prefix_X20 = ((n)); const typeof ((n_columns)) __unique_prefix_Y21 = ((n_columns)); (__unique_prefix_X20 / __unique_prefix_Y21 + !!(__unique_prefix_X20 % __unique_prefix_Y21 )); }); | |||
| 105 | ||||
| 106 | break_lines = lines(); | |||
| 107 | if (break_lines > 2) | |||
| 108 | break_lines--; | |||
| 109 | ||||
| 110 | /* The first page gets two extra lines, since we want to show | |||
| 111 | * a title */ | |||
| 112 | break_modulo = break_lines; | |||
| 113 | if (break_modulo > 3) | |||
| 114 | break_modulo -= 3; | |||
| 115 | ||||
| 116 | for (i = 0; i < per_column; i++) { | |||
| 117 | ||||
| 118 | for (j = 0; j < n_columns; j ++) { | |||
| 119 | _cleanup_free___attribute__((cleanup(freep))) char *e = NULL((void*)0); | |||
| 120 | ||||
| 121 | if (j * per_column + i >= n) | |||
| 122 | break; | |||
| 123 | ||||
| 124 | e = ellipsize(x[j * per_column + i], width, percentage); | |||
| 125 | if (!e) | |||
| 126 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 126, __func__); | |||
| 127 | ||||
| 128 | printf("%4zu) %-*s", j * per_column + i + 1, width, e); | |||
| 129 | } | |||
| 130 | ||||
| 131 | putchar('\n'); | |||
| 132 | ||||
| 133 | /* on the first screen we reserve 2 extra lines for the title */ | |||
| 134 | if (i % break_lines == break_modulo) { | |||
| 135 | if (!press_any_key()) | |||
| 136 | return 0; | |||
| 137 | } | |||
| 138 | } | |||
| 139 | ||||
| 140 | return 0; | |||
| 141 | } | |||
| 142 | ||||
| 143 | static int prompt_loop(const char *text, char **l, bool_Bool (*is_valid)(const char *name), char **ret) { | |||
| 144 | int r; | |||
| 145 | ||||
| 146 | assert(text)do { if ((__builtin_expect(!!(!(text)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("text"), "../src/firstboot/firstboot.c", 146, __PRETTY_FUNCTION__); } while (0); | |||
| 147 | assert(is_valid)do { if ((__builtin_expect(!!(!(is_valid)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("is_valid"), "../src/firstboot/firstboot.c" , 147, __PRETTY_FUNCTION__); } while (0); | |||
| 148 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/firstboot/firstboot.c", 148 , __PRETTY_FUNCTION__); } while (0); | |||
| 149 | ||||
| 150 | for (;;) { | |||
| 151 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0); | |||
| 152 | unsigned u; | |||
| 153 | ||||
| 154 | r = ask_string(&p, "%s %s (empty to skip): ", special_glyph(TRIANGULAR_BULLET), text); | |||
| 155 | if (r < 0) | |||
| 156 | return log_error_errno(r, "Failed to query user: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 156, __func__, "Failed to query user: %m" ) : -abs(_e); }); | |||
| 157 | ||||
| 158 | if (isempty(p)) { | |||
| 159 | log_warning("No data entered, skipping.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 159, __func__, "No data entered, skipping." ) : -abs(_e); }); | |||
| 160 | return 0; | |||
| 161 | } | |||
| 162 | ||||
| 163 | r = safe_atou(p, &u); | |||
| 164 | if (r >= 0) { | |||
| 165 | char *c; | |||
| 166 | ||||
| 167 | if (u <= 0 || u > strv_length(l)) { | |||
| 168 | log_error("Specified entry number out of range.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 168, __func__, "Specified entry number out of range." ) : -abs(_e); }); | |||
| 169 | continue; | |||
| 170 | } | |||
| 171 | ||||
| 172 | log_info("Selected '%s'.", l[u-1])({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 172, __func__, "Selected '%s'." , l[u-1]) : -abs(_e); }); | |||
| 173 | ||||
| 174 | c = strdup(l[u-1]); | |||
| 175 | if (!c) | |||
| 176 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 176, __func__); | |||
| 177 | ||||
| 178 | free(*ret); | |||
| 179 | *ret = c; | |||
| 180 | return 0; | |||
| 181 | } | |||
| 182 | ||||
| 183 | if (!is_valid(p)) { | |||
| 184 | log_error("Entered data invalid.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 184, __func__, "Entered data invalid." ) : -abs(_e); }); | |||
| 185 | continue; | |||
| 186 | } | |||
| 187 | ||||
| 188 | free(*ret); | |||
| 189 | *ret = p; | |||
| 190 | p = 0; | |||
| 191 | return 0; | |||
| 192 | } | |||
| 193 | } | |||
| 194 | ||||
| 195 | static bool_Bool locale_is_ok(const char *name) { | |||
| 196 | ||||
| 197 | if (arg_root) | |||
| 198 | return locale_is_valid(name); | |||
| 199 | ||||
| 200 | return locale_is_installed(name) > 0; | |||
| 201 | } | |||
| 202 | ||||
| 203 | static int prompt_locale(void) { | |||
| 204 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **locales = NULL((void*)0); | |||
| 205 | int r; | |||
| 206 | ||||
| 207 | if (arg_locale || arg_locale_messages) | |||
| 208 | return 0; | |||
| 209 | ||||
| 210 | if (!arg_prompt_locale) | |||
| 211 | return 0; | |||
| 212 | ||||
| 213 | r = get_locales(&locales); | |||
| 214 | if (r < 0) | |||
| 215 | return log_error_errno(r, "Cannot query locales list: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 215, __func__, "Cannot query locales list: %m" ) : -abs(_e); }); | |||
| 216 | ||||
| 217 | print_welcome(); | |||
| 218 | ||||
| 219 | printf("\nAvailable Locales:\n\n"); | |||
| 220 | r = show_menu(locales, 3, 22, 60); | |||
| 221 | if (r < 0) | |||
| 222 | return r; | |||
| 223 | ||||
| 224 | putchar('\n'); | |||
| 225 | ||||
| 226 | r = prompt_loop("Please enter system locale name or number", locales, locale_is_ok, &arg_locale); | |||
| 227 | if (r < 0) | |||
| 228 | return r; | |||
| 229 | ||||
| 230 | if (isempty(arg_locale)) | |||
| 231 | return 0; | |||
| 232 | ||||
| 233 | r = prompt_loop("Please enter system message locale name or number", locales, locale_is_ok, &arg_locale_messages); | |||
| 234 | if (r < 0) | |||
| 235 | return r; | |||
| 236 | ||||
| 237 | return 0; | |||
| 238 | } | |||
| 239 | ||||
| 240 | static int process_locale(void) { | |||
| 241 | const char *etc_localeconf; | |||
| 242 | char* locales[3]; | |||
| 243 | unsigned i = 0; | |||
| 244 | int r; | |||
| 245 | ||||
| 246 | etc_localeconf = prefix_roota(arg_root, "/etc/locale.conf")({ const char* _path = ("/etc/locale.conf"), *_root = (arg_root ), *_ret; char *_p, *_n; size_t _l; while (_path[0] == '/' && _path[1] == '/') _path ++; if (empty_or_root(_root)) _ret = _path ; else { _l = strlen(_root) + 1 + strlen(_path) + 1; _n = __builtin_alloca (_l); _p = stpcpy(_n, _root); while (_p > _n && _p [-1] == '/') _p--; if (_path[0] != '/') *(_p++) = '/'; strcpy (_p, _path); _ret = _n; } _ret; }); | |||
| 247 | if (laccess(etc_localeconf, F_OK)faccessat(-100, (etc_localeconf), (0), 0x100) >= 0) | |||
| 248 | return 0; | |||
| 249 | ||||
| 250 | if (arg_copy_locale && arg_root) { | |||
| 251 | ||||
| 252 | mkdir_parents(etc_localeconf, 0755); | |||
| 253 | r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0, COPY_REFLINK); | |||
| 254 | if (r != -ENOENT2) { | |||
| 255 | if (r < 0) | |||
| 256 | return log_error_errno(r, "Failed to copy %s: %m", etc_localeconf)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 256, __func__, "Failed to copy %s: %m" , etc_localeconf) : -abs(_e); }); | |||
| 257 | ||||
| 258 | log_info("%s copied.", etc_localeconf)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 258, __func__, "%s copied." , etc_localeconf) : -abs(_e); }); | |||
| 259 | return 0; | |||
| 260 | } | |||
| 261 | } | |||
| 262 | ||||
| 263 | r = prompt_locale(); | |||
| 264 | if (r < 0) | |||
| 265 | return r; | |||
| 266 | ||||
| 267 | if (!isempty(arg_locale)) | |||
| 268 | locales[i++] = strjoina("LANG=", arg_locale)({ const char *_appendees_[] = { "LANG=", arg_locale }; char * _d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 269 | if (!isempty(arg_locale_messages) && !streq(arg_locale_messages, arg_locale)(strcmp((arg_locale_messages),(arg_locale)) == 0)) | |||
| 270 | locales[i++] = strjoina("LC_MESSAGES=", arg_locale_messages)({ const char *_appendees_[] = { "LC_MESSAGES=", arg_locale_messages }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 271 | ||||
| 272 | if (i == 0) | |||
| 273 | return 0; | |||
| 274 | ||||
| 275 | locales[i] = NULL((void*)0); | |||
| 276 | ||||
| 277 | mkdir_parents(etc_localeconf, 0755); | |||
| 278 | r = write_env_file(etc_localeconf, locales); | |||
| 279 | if (r < 0) | |||
| 280 | return log_error_errno(r, "Failed to write %s: %m", etc_localeconf)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 280, __func__, "Failed to write %s: %m" , etc_localeconf) : -abs(_e); }); | |||
| 281 | ||||
| 282 | log_info("%s written.", etc_localeconf)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 282, __func__, "%s written." , etc_localeconf) : -abs(_e); }); | |||
| 283 | return 0; | |||
| 284 | } | |||
| 285 | ||||
| 286 | static int prompt_keymap(void) { | |||
| 287 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **kmaps = NULL((void*)0); | |||
| 288 | int r; | |||
| 289 | ||||
| 290 | if (arg_keymap) | |||
| 291 | return 0; | |||
| 292 | ||||
| 293 | if (!arg_prompt_keymap) | |||
| 294 | return 0; | |||
| 295 | ||||
| 296 | r = get_keymaps(&kmaps); | |||
| 297 | if (r == -ENOENT2) /* no keymaps installed */ | |||
| 298 | return r; | |||
| 299 | if (r < 0) | |||
| 300 | return log_error_errno(r, "Failed to read keymaps: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 300, __func__, "Failed to read keymaps: %m" ) : -abs(_e); }); | |||
| 301 | ||||
| 302 | print_welcome(); | |||
| 303 | ||||
| 304 | printf("\nAvailable keymaps:\n\n"); | |||
| 305 | r = show_menu(kmaps, 3, 22, 60); | |||
| 306 | if (r < 0) | |||
| 307 | return r; | |||
| 308 | ||||
| 309 | putchar('\n'); | |||
| 310 | ||||
| 311 | return prompt_loop("Please enter system keymap name or number", | |||
| 312 | kmaps, keymap_is_valid, &arg_keymap); | |||
| 313 | } | |||
| 314 | ||||
| 315 | static int process_keymap(void) { | |||
| 316 | const char *etc_vconsoleconf; | |||
| 317 | char **keymap; | |||
| 318 | int r; | |||
| 319 | ||||
| 320 | etc_vconsoleconf = prefix_roota(arg_root, "/etc/vconsole.conf")({ const char* _path = ("/etc/vconsole.conf"), *_root = (arg_root ), *_ret; char *_p, *_n; size_t _l; while (_path[0] == '/' && _path[1] == '/') _path ++; if (empty_or_root(_root)) _ret = _path ; else { _l = strlen(_root) + 1 + strlen(_path) + 1; _n = __builtin_alloca (_l); _p = stpcpy(_n, _root); while (_p > _n && _p [-1] == '/') _p--; if (_path[0] != '/') *(_p++) = '/'; strcpy (_p, _path); _ret = _n; } _ret; }); | |||
| 321 | if (laccess(etc_vconsoleconf, F_OK)faccessat(-100, (etc_vconsoleconf), (0), 0x100) >= 0) | |||
| 322 | return 0; | |||
| 323 | ||||
| 324 | if (arg_copy_keymap && arg_root) { | |||
| 325 | ||||
| 326 | mkdir_parents(etc_vconsoleconf, 0755); | |||
| 327 | r = copy_file("/etc/vconsole.conf", etc_vconsoleconf, 0, 0644, 0, COPY_REFLINK); | |||
| 328 | if (r != -ENOENT2) { | |||
| 329 | if (r < 0) | |||
| 330 | return log_error_errno(r, "Failed to copy %s: %m", etc_vconsoleconf)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 330, __func__, "Failed to copy %s: %m" , etc_vconsoleconf) : -abs(_e); }); | |||
| 331 | ||||
| 332 | log_info("%s copied.", etc_vconsoleconf)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 332, __func__, "%s copied." , etc_vconsoleconf) : -abs(_e); }); | |||
| 333 | return 0; | |||
| 334 | } | |||
| 335 | } | |||
| 336 | ||||
| 337 | r = prompt_keymap(); | |||
| 338 | if (r == -ENOENT2) | |||
| 339 | return 0; /* don't fail if no keymaps are installed */ | |||
| 340 | if (r < 0) | |||
| 341 | return r; | |||
| 342 | ||||
| 343 | if (isempty(arg_keymap)) | |||
| 344 | return 0; | |||
| 345 | ||||
| 346 | keymap = STRV_MAKE(strjoina("KEYMAP=", arg_keymap))((char**) ((const char*[]) { ({ const char *_appendees_[] = { "KEYMAP=", arg_keymap }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _len_ += strlen (_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }), ((void*)0) })); | |||
| 347 | ||||
| 348 | r = mkdir_parents(etc_vconsoleconf, 0755); | |||
| 349 | if (r < 0) | |||
| 350 | return log_error_errno(r, "Failed to create the parent directory of %s: %m", etc_vconsoleconf)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 350, __func__, "Failed to create the parent directory of %s: %m" , etc_vconsoleconf) : -abs(_e); }); | |||
| 351 | ||||
| 352 | r = write_env_file(etc_vconsoleconf, keymap); | |||
| 353 | if (r < 0) | |||
| 354 | return log_error_errno(r, "Failed to write %s: %m", etc_vconsoleconf)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 354, __func__, "Failed to write %s: %m" , etc_vconsoleconf) : -abs(_e); }); | |||
| 355 | ||||
| 356 | log_info("%s written.", etc_vconsoleconf)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 356, __func__, "%s written." , etc_vconsoleconf) : -abs(_e); }); | |||
| 357 | return 0; | |||
| 358 | } | |||
| 359 | ||||
| 360 | static bool_Bool timezone_is_valid_log_error(const char *name) { | |||
| 361 | return timezone_is_valid(name, LOG_ERR3); | |||
| 362 | } | |||
| 363 | ||||
| 364 | static int prompt_timezone(void) { | |||
| 365 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **zones = NULL((void*)0); | |||
| 366 | int r; | |||
| 367 | ||||
| 368 | if (arg_timezone) | |||
| 369 | return 0; | |||
| 370 | ||||
| 371 | if (!arg_prompt_timezone) | |||
| 372 | return 0; | |||
| 373 | ||||
| 374 | r = get_timezones(&zones); | |||
| 375 | if (r < 0) | |||
| 376 | return log_error_errno(r, "Cannot query timezone list: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 376, __func__, "Cannot query timezone list: %m" ) : -abs(_e); }); | |||
| 377 | ||||
| 378 | print_welcome(); | |||
| 379 | ||||
| 380 | printf("\nAvailable Time Zones:\n\n"); | |||
| 381 | r = show_menu(zones, 3, 22, 30); | |||
| 382 | if (r < 0) | |||
| 383 | return r; | |||
| 384 | ||||
| 385 | putchar('\n'); | |||
| 386 | ||||
| 387 | r = prompt_loop("Please enter timezone name or number", zones, timezone_is_valid_log_error, &arg_timezone); | |||
| 388 | if (r < 0) | |||
| 389 | return r; | |||
| 390 | ||||
| 391 | return 0; | |||
| 392 | } | |||
| 393 | ||||
| 394 | static int process_timezone(void) { | |||
| 395 | const char *etc_localtime, *e; | |||
| 396 | int r; | |||
| 397 | ||||
| 398 | etc_localtime = prefix_roota(arg_root, "/etc/localtime")({ const char* _path = ("/etc/localtime"), *_root = (arg_root ), *_ret; char *_p, *_n; size_t _l; while (_path[0] == '/' && _path[1] == '/') _path ++; if (empty_or_root(_root)) _ret = _path ; else { _l = strlen(_root) + 1 + strlen(_path) + 1; _n = __builtin_alloca (_l); _p = stpcpy(_n, _root); while (_p > _n && _p [-1] == '/') _p--; if (_path[0] != '/') *(_p++) = '/'; strcpy (_p, _path); _ret = _n; } _ret; }); | |||
| 399 | if (laccess(etc_localtime, F_OK)faccessat(-100, (etc_localtime), (0), 0x100) >= 0) | |||
| 400 | return 0; | |||
| 401 | ||||
| 402 | if (arg_copy_timezone && arg_root) { | |||
| 403 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0); | |||
| 404 | ||||
| 405 | r = readlink_malloc("/etc/localtime", &p); | |||
| 406 | if (r != -ENOENT2) { | |||
| 407 | if (r < 0) | |||
| 408 | return log_error_errno(r, "Failed to read host timezone: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 408, __func__, "Failed to read host timezone: %m" ) : -abs(_e); }); | |||
| 409 | ||||
| 410 | mkdir_parents(etc_localtime, 0755); | |||
| 411 | if (symlink(p, etc_localtime) < 0) | |||
| 412 | return log_error_errno(errno, "Failed to create %s symlink: %m", etc_localtime)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/firstboot/firstboot.c", 412, __func__ , "Failed to create %s symlink: %m", etc_localtime) : -abs(_e ); }); | |||
| 413 | ||||
| 414 | log_info("%s copied.", etc_localtime)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 414, __func__, "%s copied." , etc_localtime) : -abs(_e); }); | |||
| 415 | return 0; | |||
| 416 | } | |||
| 417 | } | |||
| 418 | ||||
| 419 | r = prompt_timezone(); | |||
| 420 | if (r < 0) | |||
| 421 | return r; | |||
| 422 | ||||
| 423 | if (isempty(arg_timezone)) | |||
| 424 | return 0; | |||
| 425 | ||||
| 426 | e = strjoina("../usr/share/zoneinfo/", arg_timezone)({ const char *_appendees_[] = { "../usr/share/zoneinfo/", arg_timezone }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 427 | ||||
| 428 | mkdir_parents(etc_localtime, 0755); | |||
| 429 | if (symlink(e, etc_localtime) < 0) | |||
| 430 | return log_error_errno(errno, "Failed to create %s symlink: %m", etc_localtime)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/firstboot/firstboot.c", 430, __func__ , "Failed to create %s symlink: %m", etc_localtime) : -abs(_e ); }); | |||
| 431 | ||||
| 432 | log_info("%s written", etc_localtime)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 432, __func__, "%s written" , etc_localtime) : -abs(_e); }); | |||
| 433 | return 0; | |||
| 434 | } | |||
| 435 | ||||
| 436 | static int prompt_hostname(void) { | |||
| 437 | int r; | |||
| 438 | ||||
| 439 | if (arg_hostname) | |||
| 440 | return 0; | |||
| 441 | ||||
| 442 | if (!arg_prompt_hostname) | |||
| 443 | return 0; | |||
| 444 | ||||
| 445 | print_welcome(); | |||
| 446 | putchar('\n'); | |||
| 447 | ||||
| 448 | for (;;) { | |||
| 449 | _cleanup_free___attribute__((cleanup(freep))) char *h = NULL((void*)0); | |||
| 450 | ||||
| 451 | r = ask_string(&h, "%s Please enter hostname for new system (empty to skip): ", special_glyph(TRIANGULAR_BULLET)); | |||
| 452 | if (r < 0) | |||
| 453 | return log_error_errno(r, "Failed to query hostname: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 453, __func__, "Failed to query hostname: %m" ) : -abs(_e); }); | |||
| 454 | ||||
| 455 | if (isempty(h)) { | |||
| 456 | log_warning("No hostname entered, skipping.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 456, __func__, "No hostname entered, skipping." ) : -abs(_e); }); | |||
| 457 | break; | |||
| 458 | } | |||
| 459 | ||||
| 460 | if (!hostname_is_valid(h, true1)) { | |||
| 461 | log_error("Specified hostname invalid.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 461, __func__, "Specified hostname invalid." ) : -abs(_e); }); | |||
| 462 | continue; | |||
| 463 | } | |||
| 464 | ||||
| 465 | /* Get rid of the trailing dot that we allow, but don't want to see */ | |||
| 466 | arg_hostname = hostname_cleanup(h); | |||
| 467 | h = NULL((void*)0); | |||
| 468 | break; | |||
| 469 | } | |||
| 470 | ||||
| 471 | return 0; | |||
| 472 | } | |||
| 473 | ||||
| 474 | static int process_hostname(void) { | |||
| 475 | const char *etc_hostname; | |||
| 476 | int r; | |||
| 477 | ||||
| 478 | etc_hostname = prefix_roota(arg_root, "/etc/hostname")({ const char* _path = ("/etc/hostname"), *_root = (arg_root) , *_ret; char *_p, *_n; size_t _l; while (_path[0] == '/' && _path[1] == '/') _path ++; if (empty_or_root(_root)) _ret = _path ; else { _l = strlen(_root) + 1 + strlen(_path) + 1; _n = __builtin_alloca (_l); _p = stpcpy(_n, _root); while (_p > _n && _p [-1] == '/') _p--; if (_path[0] != '/') *(_p++) = '/'; strcpy (_p, _path); _ret = _n; } _ret; }); | |||
| 
 | ||||
| 479 | if (laccess(etc_hostname, F_OK)faccessat(-100, (etc_hostname), (0), 0x100) >= 0) | |||
| 480 | return 0; | |||
| 481 | ||||
| 482 | r = prompt_hostname(); | |||
| 483 | if (r < 0) | |||
| 484 | return r; | |||
| 485 | ||||
| 486 | if (isempty(arg_hostname)) | |||
| 487 | return 0; | |||
| 488 | ||||
| 489 | mkdir_parents(etc_hostname, 0755); | |||
| 490 | r = write_string_file(etc_hostname, arg_hostname, | |||
| 491 | WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_SYNC); | |||
| 492 | if (r < 0) | |||
| 493 | return log_error_errno(r, "Failed to write %s: %m", etc_hostname)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 493, __func__, "Failed to write %s: %m" , etc_hostname) : -abs(_e); }); | |||
| 494 | ||||
| 495 | log_info("%s written.", etc_hostname)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 495, __func__, "%s written." , etc_hostname) : -abs(_e); }); | |||
| 496 | return 0; | |||
| 497 | } | |||
| 498 | ||||
| 499 | static int process_machine_id(void) { | |||
| 500 | const char *etc_machine_id; | |||
| 501 | char id[SD_ID128_STRING_MAX33]; | |||
| 502 | int r; | |||
| 503 | ||||
| 504 | etc_machine_id = prefix_roota(arg_root, "/etc/machine-id")({ const char* _path = ("/etc/machine-id"), *_root = (arg_root ), *_ret; char *_p, *_n; size_t _l; while (_path[0] == '/' && _path[1] == '/') _path ++; if (empty_or_root(_root)) _ret = _path ; else { _l = strlen(_root) + 1 + strlen(_path) + 1; _n = __builtin_alloca (_l); _p = stpcpy(_n, _root); while (_p > _n && _p [-1] == '/') _p--; if (_path[0] != '/') *(_p++) = '/'; strcpy (_p, _path); _ret = _n; } _ret; }); | |||
| 505 | if (laccess(etc_machine_id, F_OK)faccessat(-100, (etc_machine_id), (0), 0x100) >= 0) | |||
| 506 | return 0; | |||
| 507 | ||||
| 508 | if (sd_id128_is_null(arg_machine_id)) | |||
| 509 | return 0; | |||
| 510 | ||||
| 511 | mkdir_parents(etc_machine_id, 0755); | |||
| 512 | r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id), | |||
| 513 | WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_SYNC); | |||
| 514 | if (r < 0) | |||
| 515 | return log_error_errno(r, "Failed to write machine id: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 515, __func__, "Failed to write machine id: %m" ) : -abs(_e); }); | |||
| 516 | ||||
| 517 | log_info("%s written.", etc_machine_id)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 517, __func__, "%s written." , etc_machine_id) : -abs(_e); }); | |||
| 518 | return 0; | |||
| 519 | } | |||
| 520 | ||||
| 521 | static int prompt_root_password(void) { | |||
| 522 | const char *msg1, *msg2, *etc_shadow; | |||
| 523 | int r; | |||
| 524 | ||||
| 525 | if (arg_root_password) | |||
| 526 | return 0; | |||
| 527 | ||||
| 528 | if (!arg_prompt_root_password) | |||
| 529 | return 0; | |||
| 530 | ||||
| 531 | etc_shadow = prefix_roota(arg_root, "/etc/shadow")({ const char* _path = ("/etc/shadow"), *_root = (arg_root), * _ret; char *_p, *_n; size_t _l; while (_path[0] == '/' && _path[1] == '/') _path ++; if (empty_or_root(_root)) _ret = _path ; else { _l = strlen(_root) + 1 + strlen(_path) + 1; _n = __builtin_alloca (_l); _p = stpcpy(_n, _root); while (_p > _n && _p [-1] == '/') _p--; if (_path[0] != '/') *(_p++) = '/'; strcpy (_p, _path); _ret = _n; } _ret; }); | |||
| 532 | if (laccess(etc_shadow, F_OK)faccessat(-100, (etc_shadow), (0), 0x100) >= 0) | |||
| 533 | return 0; | |||
| 534 | ||||
| 535 | print_welcome(); | |||
| 536 | putchar('\n'); | |||
| 537 | ||||
| 538 | msg1 = strjoina(special_glyph(TRIANGULAR_BULLET), " Please enter a new root password (empty to skip): ")({ const char *_appendees_[] = { special_glyph(TRIANGULAR_BULLET ), " Please enter a new root password (empty to skip): " }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 539 | msg2 = strjoina(special_glyph(TRIANGULAR_BULLET), " Please enter new root password again: ")({ const char *_appendees_[] = { special_glyph(TRIANGULAR_BULLET ), " Please enter new root password again: " }; char *_d_, *_p_ ; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 540 | ||||
| 541 | for (;;) { | |||
| 542 | _cleanup_string_free_erase___attribute__((cleanup(string_free_erasep))) char *a = NULL((void*)0), *b = NULL((void*)0); | |||
| 543 | ||||
| 544 | r = ask_password_tty(-1, msg1, NULL((void*)0), 0, 0, NULL((void*)0), &a); | |||
| 545 | if (r < 0) | |||
| 546 | return log_error_errno(r, "Failed to query root password: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 546, __func__, "Failed to query root password: %m" ) : -abs(_e); }); | |||
| 547 | ||||
| 548 | if (isempty(a)) { | |||
| 549 | log_warning("No password entered, skipping.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 549, __func__, "No password entered, skipping." ) : -abs(_e); }); | |||
| 550 | break; | |||
| 551 | } | |||
| 552 | ||||
| 553 | r = ask_password_tty(-1, msg2, NULL((void*)0), 0, 0, NULL((void*)0), &b); | |||
| 554 | if (r < 0) | |||
| 555 | return log_error_errno(r, "Failed to query root password: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 555, __func__, "Failed to query root password: %m" ) : -abs(_e); }); | |||
| 556 | ||||
| 557 | if (!streq(a, b)(strcmp((a),(b)) == 0)) { | |||
| 558 | log_error("Entered passwords did not match, please try again.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 558, __func__, "Entered passwords did not match, please try again." ) : -abs(_e); }); | |||
| 559 | continue; | |||
| 560 | } | |||
| 561 | ||||
| 562 | arg_root_password = TAKE_PTR(a)({ typeof(a) _ptr_ = (a); (a) = ((void*)0); _ptr_; }); | |||
| 563 | break; | |||
| 564 | } | |||
| 565 | ||||
| 566 | return 0; | |||
| 567 | } | |||
| 568 | ||||
| 569 | static int write_root_shadow(const char *path, const struct spwd *p) { | |||
| 570 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 571 | int r; | |||
| 572 | ||||
| 573 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/firstboot/firstboot.c", 573, __PRETTY_FUNCTION__); } while (0); | |||
| 574 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/firstboot/firstboot.c", 574 , __PRETTY_FUNCTION__); } while (0); | |||
| 575 | ||||
| 576 | RUN_WITH_UMASK(0777)for (__attribute__((cleanup(_reset_umask_))) struct _umask_struct_ _saved_umask_ = { umask(0777), 0 }; !_saved_umask_.quit ; _saved_umask_ .quit = 1) | |||
| 577 | f = fopen(path, "wex"); | |||
| 578 | if (!f) | |||
| 579 | return -errno(*__errno_location ()); | |||
| 580 | ||||
| 581 | r = putspent_sane(p, f); | |||
| 582 | if (r < 0) | |||
| 583 | return r; | |||
| 584 | ||||
| 585 | return fflush_sync_and_check(f); | |||
| 586 | } | |||
| 587 | ||||
| 588 | static int process_root_password(void) { | |||
| 589 | ||||
| 590 | static const char table[] = | |||
| 591 | "abcdefghijklmnopqrstuvwxyz" | |||
| 592 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |||
| 593 | "0123456789" | |||
| 594 | "./"; | |||
| 595 | ||||
| 596 | struct spwd item = { | |||
| 597 | .sp_namp = (char*) "root", | |||
| 598 | .sp_min = -1, | |||
| 599 | .sp_max = -1, | |||
| 600 | .sp_warn = -1, | |||
| 601 | .sp_inact = -1, | |||
| 602 | .sp_expire = -1, | |||
| 603 | .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */ | |||
| 604 | }; | |||
| 605 | ||||
| 606 | _cleanup_close___attribute__((cleanup(closep))) int lock = -1; | |||
| 607 | char salt[3+16+1+1]; | |||
| 608 | uint8_t raw[16]; | |||
| 609 | unsigned i; | |||
| 610 | char *j; | |||
| 611 | ||||
| 612 | const char *etc_shadow; | |||
| 613 | int r; | |||
| 614 | ||||
| 615 | etc_shadow = prefix_roota(arg_root, "/etc/shadow")({ const char* _path = ("/etc/shadow"), *_root = (arg_root), * _ret; char *_p, *_n; size_t _l; while (_path[0] == '/' && _path[1] == '/') _path ++; if (empty_or_root(_root)) _ret = _path ; else { _l = strlen(_root) + 1 + strlen(_path) + 1; _n = __builtin_alloca (_l); _p = stpcpy(_n, _root); while (_p > _n && _p [-1] == '/') _p--; if (_path[0] != '/') *(_p++) = '/'; strcpy (_p, _path); _ret = _n; } _ret; }); | |||
| 616 | if (laccess(etc_shadow, F_OK)faccessat(-100, (etc_shadow), (0), 0x100) >= 0) | |||
| 617 | return 0; | |||
| 618 | ||||
| 619 | mkdir_parents(etc_shadow, 0755); | |||
| 620 | ||||
| 621 | lock = take_etc_passwd_lock(arg_root); | |||
| 622 | if (lock < 0) | |||
| 623 | return log_error_errno(lock, "Failed to take a lock: %m")({ int _level = ((3)), _e = ((lock)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 623, __func__, "Failed to take a lock: %m" ) : -abs(_e); }); | |||
| 624 | ||||
| 625 | if (arg_copy_root_password && arg_root) { | |||
| 626 | struct spwd *p; | |||
| 627 | ||||
| 628 | errno(*__errno_location ()) = 0; | |||
| 629 | p = getspnam("root"); | |||
| 630 | if (p || errno(*__errno_location ()) != ENOENT2) { | |||
| 631 | if (!p) { | |||
| 632 | if (!errno(*__errno_location ())) | |||
| 633 | errno(*__errno_location ()) = EIO5; | |||
| 634 | ||||
| 635 | return log_error_errno(errno, "Failed to find shadow entry for root: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/firstboot/firstboot.c", 635, __func__ , "Failed to find shadow entry for root: %m") : -abs(_e); }); | |||
| 636 | } | |||
| 637 | ||||
| 638 | r = write_root_shadow(etc_shadow, p); | |||
| 639 | if (r < 0) | |||
| 640 | return log_error_errno(r, "Failed to write %s: %m", etc_shadow)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 640, __func__, "Failed to write %s: %m" , etc_shadow) : -abs(_e); }); | |||
| 641 | ||||
| 642 | log_info("%s copied.", etc_shadow)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 642, __func__, "%s copied." , etc_shadow) : -abs(_e); }); | |||
| 643 | return 0; | |||
| 644 | } | |||
| 645 | } | |||
| 646 | ||||
| 647 | r = prompt_root_password(); | |||
| 648 | if (r < 0) | |||
| 649 | return r; | |||
| 650 | ||||
| 651 | if (!arg_root_password) | |||
| 652 | return 0; | |||
| 653 | ||||
| 654 | r = acquire_random_bytes(raw, 16, true1); | |||
| 655 | if (r < 0) | |||
| 656 | return log_error_errno(r, "Failed to get salt: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 656, __func__, "Failed to get salt: %m" ) : -abs(_e); }); | |||
| 657 | ||||
| 658 | /* We only bother with SHA512 hashed passwords, the rest is legacy, and we don't do legacy. */ | |||
| 659 | assert_cc(sizeof(table) == 64 + 1)GCC diagnostic push
; GCC diagnostic ignored "-Wdeclaration-after-statement" ; struct _assert_struct_22 { char x[(sizeof(table) == 64 + 1 ) ? 0 : -1]; }; GCC diagnostic pop ; | |||
| 660 | j = stpcpy(salt, "$6$"); | |||
| 661 | for (i = 0; i < 16; i++) | |||
| 662 | j[i] = table[raw[i] & 63]; | |||
| 663 | j[i++] = '$'; | |||
| 664 | j[i] = 0; | |||
| 665 | ||||
| 666 | errno(*__errno_location ()) = 0; | |||
| 667 | item.sp_pwdp = crypt(arg_root_password, salt); | |||
| 668 | if (!item.sp_pwdp) { | |||
| 669 | if (!errno(*__errno_location ())) | |||
| 670 | errno(*__errno_location ()) = EINVAL22; | |||
| 671 | ||||
| 672 | return log_error_errno(errno, "Failed to encrypt password: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/firstboot/firstboot.c", 672, __func__ , "Failed to encrypt password: %m") : -abs(_e); }); | |||
| 673 | } | |||
| 674 | ||||
| 675 | item.sp_lstchg = (long) (now(CLOCK_REALTIME0) / USEC_PER_DAY((usec_t) (24ULL*((usec_t) (60ULL*((usec_t) (60ULL*((usec_t) 1000000ULL )))))))); | |||
| 676 | ||||
| 677 | r = write_root_shadow(etc_shadow, &item); | |||
| 678 | if (r < 0) | |||
| 679 | return log_error_errno(r, "Failed to write %s: %m", etc_shadow)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 679, __func__, "Failed to write %s: %m" , etc_shadow) : -abs(_e); }); | |||
| 680 | ||||
| 681 | log_info("%s written.", etc_shadow)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 681, __func__, "%s written." , etc_shadow) : -abs(_e); }); | |||
| 682 | return 0; | |||
| 683 | } | |||
| 684 | ||||
| 685 | static void help(void) { | |||
| 686 | printf("%s [OPTIONS...]\n\n" | |||
| 687 | "Configures basic settings of the system.\n\n" | |||
| 688 | " -h --help Show this help\n" | |||
| 689 | " --version Show package version\n" | |||
| 690 | " --root=PATH Operate on an alternate filesystem root\n" | |||
| 691 | " --locale=LOCALE Set primary locale (LANG=)\n" | |||
| 692 | " --locale-messages=LOCALE Set message locale (LC_MESSAGES=)\n" | |||
| 693 | " --keymap=KEYMAP Set keymap\n" | |||
| 694 | " --timezone=TIMEZONE Set timezone\n" | |||
| 695 | " --hostname=NAME Set host name\n" | |||
| 696 | " --machine-ID=ID Set machine ID\n" | |||
| 697 | " --root-password=PASSWORD Set root password\n" | |||
| 698 | " --root-password-file=FILE Set root password from file\n" | |||
| 699 | " --prompt-locale Prompt the user for locale settings\n" | |||
| 700 | " --prompt-keymap Prompt the user for keymap settings\n" | |||
| 701 | " --prompt-timezone Prompt the user for timezone\n" | |||
| 702 | " --prompt-hostname Prompt the user for hostname\n" | |||
| 703 | " --prompt-root-password Prompt the user for root password\n" | |||
| 704 | " --prompt Prompt for all of the above\n" | |||
| 705 | " --copy-locale Copy locale from host\n" | |||
| 706 | " --copy-keymap Copy keymap from host\n" | |||
| 707 | " --copy-timezone Copy timezone from host\n" | |||
| 708 | " --copy-root-password Copy root password from host\n" | |||
| 709 | " --copy Copy locale, keymap, timezone, root password\n" | |||
| 710 | " --setup-machine-id Generate a new random machine ID\n" | |||
| 711 | , program_invocation_short_name); | |||
| 712 | } | |||
| 713 | ||||
| 714 | static int parse_argv(int argc, char *argv[]) { | |||
| 715 | ||||
| 716 | enum { | |||
| 717 | ARG_VERSION = 0x100, | |||
| 718 | ARG_ROOT, | |||
| 719 | ARG_LOCALE, | |||
| 720 | ARG_LOCALE_MESSAGES, | |||
| 721 | ARG_KEYMAP, | |||
| 722 | ARG_TIMEZONE, | |||
| 723 | ARG_HOSTNAME, | |||
| 724 | ARG_MACHINE_ID, | |||
| 725 | ARG_ROOT_PASSWORD, | |||
| 726 | ARG_ROOT_PASSWORD_FILE, | |||
| 727 | ARG_PROMPT, | |||
| 728 | ARG_PROMPT_LOCALE, | |||
| 729 | ARG_PROMPT_KEYMAP, | |||
| 730 | ARG_PROMPT_TIMEZONE, | |||
| 731 | ARG_PROMPT_HOSTNAME, | |||
| 732 | ARG_PROMPT_ROOT_PASSWORD, | |||
| 733 | ARG_COPY, | |||
| 734 | ARG_COPY_LOCALE, | |||
| 735 | ARG_COPY_KEYMAP, | |||
| 736 | ARG_COPY_TIMEZONE, | |||
| 737 | ARG_COPY_ROOT_PASSWORD, | |||
| 738 | ARG_SETUP_MACHINE_ID, | |||
| 739 | }; | |||
| 740 | ||||
| 741 | static const struct option options[] = { | |||
| 742 | { "help", no_argument0, NULL((void*)0), 'h' }, | |||
| 743 | { "version", no_argument0, NULL((void*)0), ARG_VERSION }, | |||
| 744 | { "root", required_argument1, NULL((void*)0), ARG_ROOT }, | |||
| 745 | { "locale", required_argument1, NULL((void*)0), ARG_LOCALE }, | |||
| 746 | { "locale-messages", required_argument1, NULL((void*)0), ARG_LOCALE_MESSAGES }, | |||
| 747 | { "keymap", required_argument1, NULL((void*)0), ARG_KEYMAP }, | |||
| 748 | { "timezone", required_argument1, NULL((void*)0), ARG_TIMEZONE }, | |||
| 749 | { "hostname", required_argument1, NULL((void*)0), ARG_HOSTNAME }, | |||
| 750 | { "machine-id", required_argument1, NULL((void*)0), ARG_MACHINE_ID }, | |||
| 751 | { "root-password", required_argument1, NULL((void*)0), ARG_ROOT_PASSWORD }, | |||
| 752 | { "root-password-file", required_argument1, NULL((void*)0), ARG_ROOT_PASSWORD_FILE }, | |||
| 753 | { "prompt", no_argument0, NULL((void*)0), ARG_PROMPT }, | |||
| 754 | { "prompt-locale", no_argument0, NULL((void*)0), ARG_PROMPT_LOCALE }, | |||
| 755 | { "prompt-keymap", no_argument0, NULL((void*)0), ARG_PROMPT_KEYMAP }, | |||
| 756 | { "prompt-timezone", no_argument0, NULL((void*)0), ARG_PROMPT_TIMEZONE }, | |||
| 757 | { "prompt-hostname", no_argument0, NULL((void*)0), ARG_PROMPT_HOSTNAME }, | |||
| 758 | { "prompt-root-password", no_argument0, NULL((void*)0), ARG_PROMPT_ROOT_PASSWORD }, | |||
| 759 | { "copy", no_argument0, NULL((void*)0), ARG_COPY }, | |||
| 760 | { "copy-locale", no_argument0, NULL((void*)0), ARG_COPY_LOCALE }, | |||
| 761 | { "copy-keymap", no_argument0, NULL((void*)0), ARG_COPY_KEYMAP }, | |||
| 762 | { "copy-timezone", no_argument0, NULL((void*)0), ARG_COPY_TIMEZONE }, | |||
| 763 | { "copy-root-password", no_argument0, NULL((void*)0), ARG_COPY_ROOT_PASSWORD }, | |||
| 764 | { "setup-machine-id", no_argument0, NULL((void*)0), ARG_SETUP_MACHINE_ID }, | |||
| 765 | {} | |||
| 766 | }; | |||
| 767 | ||||
| 768 | int r, c; | |||
| 769 | ||||
| 770 | assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/firstboot/firstboot.c" , 770, __PRETTY_FUNCTION__); } while (0); | |||
| 771 | assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argv"), "../src/firstboot/firstboot.c", 771, __PRETTY_FUNCTION__); } while (0); | |||
| 772 | ||||
| 773 | while ((c = getopt_long(argc, argv, "h", options, NULL((void*)0))) >= 0) | |||
| 774 | ||||
| 775 | switch (c) { | |||
| 776 | ||||
| 777 | case 'h': | |||
| 778 | help(); | |||
| 779 | return 0; | |||
| 780 | ||||
| 781 | case ARG_VERSION: | |||
| 782 | return version(); | |||
| 783 | ||||
| 784 | case ARG_ROOT: | |||
| 785 | r = parse_path_argument_and_warn(optarg, true1, &arg_root); | |||
| 786 | if (r < 0) | |||
| 787 | return r; | |||
| 788 | break; | |||
| 789 | ||||
| 790 | case ARG_LOCALE: | |||
| 791 | r = free_and_strdup(&arg_locale, optarg); | |||
| 792 | if (r < 0) | |||
| 793 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 793, __func__); | |||
| 794 | ||||
| 795 | break; | |||
| 796 | ||||
| 797 | case ARG_LOCALE_MESSAGES: | |||
| 798 | r = free_and_strdup(&arg_locale_messages, optarg); | |||
| 799 | if (r < 0) | |||
| 800 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 800, __func__); | |||
| 801 | ||||
| 802 | break; | |||
| 803 | ||||
| 804 | case ARG_KEYMAP: | |||
| 805 | if (!keymap_is_valid(optarg)) { | |||
| 806 | log_error("Keymap %s is not valid.", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 806, __func__, "Keymap %s is not valid." , optarg) : -abs(_e); }); | |||
| 807 | return -EINVAL22; | |||
| 808 | } | |||
| 809 | ||||
| 810 | r = free_and_strdup(&arg_keymap, optarg); | |||
| 811 | if (r < 0) | |||
| 812 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 812, __func__); | |||
| 813 | ||||
| 814 | break; | |||
| 815 | ||||
| 816 | case ARG_TIMEZONE: | |||
| 817 | if (!timezone_is_valid(optarg, LOG_ERR3)) { | |||
| 818 | log_error("Timezone %s is not valid.", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 818, __func__, "Timezone %s is not valid." , optarg) : -abs(_e); }); | |||
| 819 | return -EINVAL22; | |||
| 820 | } | |||
| 821 | ||||
| 822 | r = free_and_strdup(&arg_timezone, optarg); | |||
| 823 | if (r < 0) | |||
| 824 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 824, __func__); | |||
| 825 | ||||
| 826 | break; | |||
| 827 | ||||
| 828 | case ARG_ROOT_PASSWORD: | |||
| 829 | r = free_and_strdup(&arg_root_password, optarg); | |||
| 830 | if (r < 0) | |||
| 831 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 831, __func__); | |||
| 832 | break; | |||
| 833 | ||||
| 834 | case ARG_ROOT_PASSWORD_FILE: | |||
| 835 | arg_root_password = mfree(arg_root_password); | |||
| 836 | ||||
| 837 | r = read_one_line_file(optarg, &arg_root_password); | |||
| 838 | if (r < 0) | |||
| 839 | return log_error_errno(r, "Failed to read %s: %m", optarg)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 839, __func__, "Failed to read %s: %m" , optarg) : -abs(_e); }); | |||
| 840 | ||||
| 841 | break; | |||
| 842 | ||||
| 843 | case ARG_HOSTNAME: | |||
| 844 | if (!hostname_is_valid(optarg, true1)) { | |||
| 845 | log_error("Host name %s is not valid.", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 845, __func__, "Host name %s is not valid." , optarg) : -abs(_e); }); | |||
| 846 | return -EINVAL22; | |||
| 847 | } | |||
| 848 | ||||
| 849 | hostname_cleanup(optarg); | |||
| 850 | r = free_and_strdup(&arg_hostname, optarg); | |||
| 851 | if (r < 0) | |||
| 852 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/firstboot/firstboot.c" , 852, __func__); | |||
| 853 | ||||
| 854 | break; | |||
| 855 | ||||
| 856 | case ARG_MACHINE_ID: | |||
| 857 | if (sd_id128_from_string(optarg, &arg_machine_id) < 0) { | |||
| 858 | log_error("Failed to parse machine id %s.", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 858, __func__, "Failed to parse machine id %s." , optarg) : -abs(_e); }); | |||
| 859 | return -EINVAL22; | |||
| 860 | } | |||
| 861 | ||||
| 862 | break; | |||
| 863 | ||||
| 864 | case ARG_PROMPT: | |||
| 865 | arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true1; | |||
| 866 | break; | |||
| 867 | ||||
| 868 | case ARG_PROMPT_LOCALE: | |||
| 869 | arg_prompt_locale = true1; | |||
| 870 | break; | |||
| 871 | ||||
| 872 | case ARG_PROMPT_KEYMAP: | |||
| 873 | arg_prompt_keymap = true1; | |||
| 874 | break; | |||
| 875 | ||||
| 876 | case ARG_PROMPT_TIMEZONE: | |||
| 877 | arg_prompt_timezone = true1; | |||
| 878 | break; | |||
| 879 | ||||
| 880 | case ARG_PROMPT_HOSTNAME: | |||
| 881 | arg_prompt_hostname = true1; | |||
| 882 | break; | |||
| 883 | ||||
| 884 | case ARG_PROMPT_ROOT_PASSWORD: | |||
| 885 | arg_prompt_root_password = true1; | |||
| 886 | break; | |||
| 887 | ||||
| 888 | case ARG_COPY: | |||
| 889 | arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password = true1; | |||
| 890 | break; | |||
| 891 | ||||
| 892 | case ARG_COPY_LOCALE: | |||
| 893 | arg_copy_locale = true1; | |||
| 894 | break; | |||
| 895 | ||||
| 896 | case ARG_COPY_KEYMAP: | |||
| 897 | arg_copy_keymap = true1; | |||
| 898 | break; | |||
| 899 | ||||
| 900 | case ARG_COPY_TIMEZONE: | |||
| 901 | arg_copy_timezone = true1; | |||
| 902 | break; | |||
| 903 | ||||
| 904 | case ARG_COPY_ROOT_PASSWORD: | |||
| 905 | arg_copy_root_password = true1; | |||
| 906 | break; | |||
| 907 | ||||
| 908 | case ARG_SETUP_MACHINE_ID: | |||
| 909 | ||||
| 910 | r = sd_id128_randomize(&arg_machine_id); | |||
| 911 | if (r < 0) | |||
| 912 | return log_error_errno(r, "Failed to generate randomized machine ID: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 912, __func__, "Failed to generate randomized machine ID: %m" ) : -abs(_e); }); | |||
| 913 | ||||
| 914 | break; | |||
| 915 | ||||
| 916 | case '?': | |||
| 917 | return -EINVAL22; | |||
| 918 | ||||
| 919 | default: | |||
| 920 | assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Unhandled option"), "../src/firstboot/firstboot.c", 920, __PRETTY_FUNCTION__ ); } while (0); | |||
| 921 | } | |||
| 922 | ||||
| 923 | /* We check if the specified locale strings are valid down here, so that we can take --root= into | |||
| 924 | * account when looking for the locale files. */ | |||
| 925 | ||||
| 926 | if (arg_locale && !locale_is_ok(arg_locale)) | |||
| 927 | return log_error_errno(EINVAL, "Locale %s is not installed.", arg_locale)({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 927, __func__, "Locale %s is not installed." , arg_locale) : -abs(_e); }); | |||
| 928 | if (arg_locale_messages && !locale_is_ok(arg_locale_messages)) | |||
| 929 | return log_error_errno(EINVAL, "Locale %s is not installed.", arg_locale_messages)({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 929, __func__, "Locale %s is not installed." , arg_locale_messages) : -abs(_e); }); | |||
| 930 | ||||
| 931 | return 1; | |||
| 932 | } | |||
| 933 | ||||
| 934 | int main(int argc, char *argv[]) { | |||
| 935 | bool_Bool enabled; | |||
| 936 | int r; | |||
| 937 | ||||
| 938 | r = parse_argv(argc, argv); | |||
| 939 | if (r <= 0) | |||
| 
 | ||||
| 940 | goto finish; | |||
| 941 | ||||
| 942 | log_set_target(LOG_TARGET_AUTO); | |||
| 943 | log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD); | |||
| 944 | log_open(); | |||
| 945 | ||||
| 946 | umask(0022); | |||
| 947 | ||||
| 948 | r = proc_cmdline_get_bool("systemd.firstboot", &enabled); | |||
| 949 | if (r < 0) { | |||
| 950 | log_error_errno(r, "Failed to parse systemd.firstboot= kernel command line argument, ignoring.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/firstboot/firstboot.c", 950, __func__, "Failed to parse systemd.firstboot= kernel command line argument, ignoring." ) : -abs(_e); }); | |||
| 951 | goto finish; | |||
| 952 | } | |||
| 953 | if (r > 0 && !enabled) { | |||
| 954 | r = 0; /* disabled */ | |||
| 955 | goto finish; | |||
| 956 | } | |||
| 957 | ||||
| 958 | r = process_locale(); | |||
| 959 | if (r 
 | |||
| 960 | goto finish; | |||
| 961 | ||||
| 962 | r = process_keymap(); | |||
| 963 | if (r 
 | |||
| 964 | goto finish; | |||
| 965 | ||||
| 966 | r = process_timezone(); | |||
| 967 | if (r 
 | |||
| 968 | goto finish; | |||
| 969 | ||||
| 970 | r = process_hostname(); | |||
| 971 | if (r < 0) | |||
| 972 | goto finish; | |||
| 973 | ||||
| 974 | r = process_machine_id(); | |||
| 975 | if (r < 0) | |||
| 976 | goto finish; | |||
| 977 | ||||
| 978 | r = process_root_password(); | |||
| 979 | if (r < 0) | |||
| 980 | goto finish; | |||
| 981 | ||||
| 982 | finish: | |||
| 983 | free(arg_root); | |||
| 984 | free(arg_locale); | |||
| 985 | free(arg_locale_messages); | |||
| 986 | free(arg_keymap); | |||
| 987 | free(arg_timezone); | |||
| 988 | free(arg_hostname); | |||
| 989 | string_erase(arg_root_password); | |||
| 990 | free(arg_root_password); | |||
| 991 | ||||
| 992 | return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0; | |||
| 993 | } |