Exemplo n.º 1
0
static int process_locale(void) {
        const char *etc_localeconf;
        char* locales[3];
        unsigned i = 0;
        int r;

        etc_localeconf = prefix_roota("/etc/locale.conf");
        if (faccessat(AT_FDCWD, etc_localeconf, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                return 0;

        if (arg_copy_locale && arg_root) {

                mkdir_parents(etc_localeconf, 0755);
                r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644);
                if (r != -ENOENT) {
                        if (r < 0) {
                                log_error("Failed to copy %s: %s", etc_localeconf, strerror(-r));
                                return r;
                        }

                        log_info("%s copied.", etc_localeconf);
                        return 0;
                }
        }

        r = prompt_locale();
        if (r < 0)
                return r;

        if (!isempty(arg_locale))
                locales[i++] = strappenda("LANG=", arg_locale);
        if (!isempty(arg_locale_messages) && !streq(arg_locale_messages, arg_locale))
                locales[i++] = strappenda("LC_MESSAGES=", arg_locale_messages);

        if (i == 0)
                return 0;

        locales[i] = NULL;

        mkdir_parents(etc_localeconf, 0755);
        r = write_env_file(etc_localeconf, locales);
        if (r < 0) {
                log_error("Failed to write %s: %s", etc_localeconf, strerror(-r));
                return r;
        }

        log_info("%s written.", etc_localeconf);
        return 0;
}
Exemplo n.º 2
0
int cg_create(const char *controller, const char *path) {
        char *fs;
        int r;

        assert(controller);
        assert(path);

        if ((r = cg_get_path(controller, path, NULL, &fs)) < 0)
                return r;

        r = mkdir_parents(fs, 0755);

        if (r >= 0) {
                if (mkdir(fs, 0755) >= 0)
                        r = 1;
                else if (errno == EEXIST)
                        r = 0;
                else
                        r = -errno;
        }

        free(fs);

        return r;
}
Exemplo n.º 3
0
static int process_hostname(void) {
        const char *etc_hostname;
        int r;

        etc_hostname = prefix_roota("/etc/hostname");
        if (faccessat(AT_FDCWD, etc_hostname, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                return 0;

        r = prompt_hostname();
        if (r < 0)
                return r;

        if (isempty(arg_hostname))
                return 0;

        mkdir_parents(etc_hostname, 0755);
        r = write_string_file(etc_hostname, arg_hostname);
        if (r < 0) {
                log_error("Failed to write %s: %s", etc_hostname, strerror(-r));
                return r;
        }

        log_info("%s written.", etc_hostname);
        return 0;
}
Exemplo n.º 4
0
void udev_watch_begin(struct udev *udev, struct udev_device *dev) {
        char filename[UTIL_PATH_SIZE];
        int wd;
        int r;

        if (inotify_fd < 0)
                return;

        log_debug("adding watch on '%s'", udev_device_get_devnode(dev));
        wd = inotify_add_watch(inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
        if (wd < 0) {
                log_error_errno(errno, "inotify_add_watch(%d, %s, %o) failed: %m",
                                inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
                return;
        }

        snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
        mkdir_parents(filename, 0755);
        unlink(filename);
        r = symlink(udev_device_get_id_filename(dev), filename);
        if (r < 0)
                log_error_errno(errno, "Failed to create symlink %s: %m", filename);

        udev_device_set_watch_handle(dev, wd);
}
Exemplo n.º 5
0
        STRV_FOREACH_PAIR(link, p, links) {
                char *f = strappenda(original_dir, *p);
                char *l = strappenda(original_dir, *link);

                assert_se(mkdir_parents(l, 0755) >= 0);
                assert_se(symlink(f, l) == 0);
        }
Exemplo n.º 6
0
static int process_machine_id(void) {
        const char *etc_machine_id;
        char id[SD_ID128_STRING_MAX];
        int r;

        etc_machine_id = prefix_roota("/etc/machine-id");
        if (faccessat(AT_FDCWD, etc_machine_id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                return 0;

        if (!arg_root)
                return 0;

        if (sd_id128_equal(arg_machine_id, SD_ID128_NULL))
                return 0;

        mkdir_parents(etc_machine_id, 0755);
        r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id));
        if (r < 0) {
                log_error("Failed to write machine id: %s", strerror(-r));
                return r;
        }

        log_info("%s written.", etc_machine_id);
        return 0;
}
Exemplo n.º 7
0
static int process_timezone(void) {
        const char *etc_localtime, *e;
        int r;

        etc_localtime = prefix_roota("/etc/localtime");
        if (faccessat(AT_FDCWD, etc_localtime, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                return 0;

        if (arg_copy_timezone && arg_root) {
                _cleanup_free_ char *p = NULL;

                r = readlink_malloc("/etc/localtime", &p);
                if (r != -ENOENT) {
                        if (r < 0) {
                                log_error("Failed to read host timezone: %s", strerror(-r));
                                return r;
                        }

                        mkdir_parents(etc_localtime, 0755);
                        if (symlink(p, etc_localtime) < 0) {
                                log_error("Failed to create %s symlink: %m", etc_localtime);
                                return -errno;
                        }

                        log_info("%s copied.", etc_localtime);
                        return 0;
                }
        }

        r = prompt_timezone();
        if (r < 0)
                return r;

        if (isempty(arg_timezone))
                return 0;

        e = strappenda("../usr/share/zoneinfo/", arg_timezone);

        mkdir_parents(etc_localtime, 0755);
        if (symlink(e, etc_localtime) < 0) {
                log_error("Failed to create %s symlink: %m", etc_localtime);
                return -errno;
        }

        log_info("%s written", etc_localtime);
        return 0;
}
Exemplo n.º 8
0
static int process_locale(void) {
        const char *etc_localeconf;
        char* locales[3];
        unsigned i = 0;
        int r;

        etc_localeconf = prefix_roota(arg_root, "/etc/locale.conf");
        if (laccess(etc_localeconf, F_OK) >= 0)
                return 0;

        if (arg_copy_locale && arg_root) {

                mkdir_parents(etc_localeconf, 0755);
                r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0, COPY_REFLINK);
                if (r != -ENOENT) {
                        if (r < 0)
                                return log_error_errno(r, "Failed to copy %s: %m", etc_localeconf);

                        log_info("%s copied.", etc_localeconf);
                        return 0;
                }
        }

        r = prompt_locale();
        if (r < 0)
                return r;

        if (!isempty(arg_locale))
                locales[i++] = strjoina("LANG=", arg_locale);
        if (!isempty(arg_locale_messages) && !streq(arg_locale_messages, arg_locale))
                locales[i++] = strjoina("LC_MESSAGES=", arg_locale_messages);

        if (i == 0)
                return 0;

        locales[i] = NULL;

        mkdir_parents(etc_localeconf, 0755);
        r = write_env_file(etc_localeconf, locales);
        if (r < 0)
                return log_error_errno(r, "Failed to write %s: %m", etc_localeconf);

        log_info("%s written.", etc_localeconf);
        return 0;
}
Exemplo n.º 9
0
        STRV_FOREACH_PAIR(link, p, links) {
                _cleanup_free_ char *f, *l;

                assert_se(f = strappend(original_dir, *p));
                assert_se(l = strappend(original_dir, *link));

                assert_se(mkdir_parents(l, 0755) >= 0);
                assert_se(symlink(f, l) == 0);
        }
Exemplo n.º 10
0
static int process_keymap(void) {
        const char *etc_vconsoleconf;
        char **keymap;
        int r;

        etc_vconsoleconf = prefix_roota(arg_root, "/etc/vconsole.conf");
        if (laccess(etc_vconsoleconf, F_OK) >= 0)
                return 0;

        if (arg_copy_keymap && arg_root) {

                mkdir_parents(etc_vconsoleconf, 0755);
                r = copy_file("/etc/vconsole.conf", etc_vconsoleconf, 0, 0644, 0, COPY_REFLINK);
                if (r != -ENOENT) {
                        if (r < 0)
                                return log_error_errno(r, "Failed to copy %s: %m", etc_vconsoleconf);

                        log_info("%s copied.", etc_vconsoleconf);
                        return 0;
                }
        }

        r = prompt_keymap();
        if (r == -ENOENT)
                return 0; /* don't fail if no keymaps are installed */
        if (r < 0)
                return r;

        if (isempty(arg_keymap))
                return 0;

        keymap = STRV_MAKE(strjoina("KEYMAP=", arg_keymap));

        r = mkdir_parents(etc_vconsoleconf, 0755);
        if (r < 0)
                return log_error_errno(r, "Failed to create the parent directory of %s: %m", etc_vconsoleconf);

        r = write_env_file(etc_vconsoleconf, keymap);
        if (r < 0)
                return log_error_errno(r, "Failed to write %s: %m", etc_vconsoleconf);

        log_info("%s written.", etc_vconsoleconf);
        return 0;
}
Exemplo n.º 11
0
static int process_timezone(void) {
        const char *etc_localtime, *e;
        int r;

        etc_localtime = prefix_roota(arg_root, "/etc/localtime");
        if (laccess(etc_localtime, F_OK) >= 0)
                return 0;

        if (arg_copy_timezone && arg_root) {
                _cleanup_free_ char *p = NULL;

                r = readlink_malloc("/etc/localtime", &p);
                if (r != -ENOENT) {
                        if (r < 0)
                                return log_error_errno(r, "Failed to read host timezone: %m");

                        mkdir_parents(etc_localtime, 0755);
                        if (symlink(p, etc_localtime) < 0)
                                return log_error_errno(errno, "Failed to create %s symlink: %m", etc_localtime);

                        log_info("%s copied.", etc_localtime);
                        return 0;
                }
        }

        r = prompt_timezone();
        if (r < 0)
                return r;

        if (isempty(arg_timezone))
                return 0;

        e = strjoina("../usr/share/zoneinfo/", arg_timezone);

        mkdir_parents(etc_localtime, 0755);
        if (symlink(e, etc_localtime) < 0)
                return log_error_errno(errno, "Failed to create %s symlink: %m", etc_localtime);

        log_info("%s written", etc_localtime);
        return 0;
}
Exemplo n.º 12
0
int sync_cgroup(pid_t pid, CGroupUnified unified_requested) {
        _cleanup_free_ char *cgroup = NULL;
        char tree[] = "/tmp/unifiedXXXXXX", pid_string[DECIMAL_STR_MAX(pid) + 1];
        bool undo_mount = false;
        const char *fn;
        int unified, r;

        unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
        if (unified < 0)
                return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");

        if ((unified > 0) == (unified_requested >= CGROUP_UNIFIED_SYSTEMD))
                return 0;

        /* When the host uses the legacy cgroup setup, but the
         * container shall use the unified hierarchy, let's make sure
         * we copy the path from the name=systemd hierarchy into the
         * unified hierarchy. Similar for the reverse situation. */

        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup);
        if (r < 0)
                return log_error_errno(r, "Failed to get control group of " PID_FMT ": %m", pid);

        /* In order to access the unified hierarchy we need to mount it */
        if (!mkdtemp(tree))
                return log_error_errno(errno, "Failed to generate temporary mount point for unified hierarchy: %m");

        if (unified)
                r = mount("cgroup", tree, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
        else
                r = mount("cgroup", tree, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
        if (r < 0) {
                r = log_error_errno(errno, "Failed to mount unified hierarchy: %m");
                goto finish;
        }

        undo_mount = true;

        fn = strjoina(tree, cgroup, "/cgroup.procs");
        (void) mkdir_parents(fn, 0755);

        sprintf(pid_string, PID_FMT, pid);
        r = write_string_file(fn, pid_string, 0);
        if (r < 0)
                log_error_errno(r, "Failed to move process: %m");

finish:
        if (undo_mount)
                (void) umount(tree);

        (void) rmdir(tree);
        return r;
}
Exemplo n.º 13
0
static void test_copy_tree(void) {
        char original_dir[] = "/tmp/test-copy_tree/";
        char copy_dir[] = "/tmp/test-copy_tree-copy/";
        char **files = STRV_MAKE("file", "dir1/file", "dir1/dir2/file", "dir1/dir2/dir3/dir4/dir5/file");
        char **links = STRV_MAKE("link", "file",
                                 "link2", "dir1/file");
        char **p, **link;

        (void) rm_rf(copy_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
        (void) rm_rf(original_dir, REMOVE_ROOT|REMOVE_PHYSICAL);

        STRV_FOREACH(p, files) {
                char *f = strjoina(original_dir, *p);

                assert_se(mkdir_parents(f, 0755) >= 0);
                assert_se(write_string_file(f, "file") == 0);
        }
Exemplo n.º 14
0
static void setup_test_dir(char *tmp_dir, const char *files, ...) {
        va_list ap;

        assert_se(mkdtemp(tmp_dir));

        va_start(ap, files);
        while (files) {
                _cleanup_free_ char *path;

                assert_se(path = strappend(tmp_dir, files));
                (void) mkdir_parents(path, 0755);
                assert_se(write_string_file(path, "foobar", WRITE_STRING_FILE_CREATE) >= 0);

                files = va_arg(ap, const char *);
        }
        va_end(ap);
}
Exemplo n.º 15
0
static void test_copy_tree(void) {
        char original_dir[] = "/tmp/test-copy_tree/";
        char copy_dir[] = "/tmp/test-copy_tree-copy/";
        char **files = STRV_MAKE("file", "dir1/file", "dir1/dir2/file", "dir1/dir2/dir3/dir4/dir5/file");
        char **links = STRV_MAKE("link", "file",
                                 "link2", "dir1/file");
        char **p, **link;

        rm_rf_dangerous(copy_dir, false, true, false);
        rm_rf_dangerous(original_dir, false, true, false);

        STRV_FOREACH(p, files) {
                char *f = strappenda(original_dir, *p);

                assert_se(mkdir_parents(f, 0755) >= 0);
                assert_se(write_string_file(f, "file") == 0);
        }
Exemplo n.º 16
0
/* manage "stack of names" with possibly specified device priorities */
static int link_update(sd_device *dev, const char *slink, bool add) {
        _cleanup_free_ char *target = NULL, *filename = NULL, *dirname = NULL;
        char name_enc[PATH_MAX];
        const char *id_filename;
        int r;

        assert(dev);
        assert(slink);

        r = device_get_id_filename(dev, &id_filename);
        if (r < 0)
                return log_device_debug_errno(dev, r, "Failed to get id_filename: %m");

        util_path_encode(slink + STRLEN("/dev"), name_enc, sizeof(name_enc));
        dirname = path_join("/run/udev/links/", name_enc);
        if (!dirname)
                return log_oom();
        filename = path_join(dirname, id_filename);
        if (!filename)
                return log_oom();

        if (!add && unlink(filename) == 0)
                (void) rmdir(dirname);

        r = link_find_prioritized(dev, add, dirname, &target);
        if (r < 0) {
                log_device_debug(dev, "No reference left, removing '%s'", slink);
                if (unlink(slink) == 0)
                        (void) rmdir_parents(slink, "/");
        } else
                (void) node_symlink(dev, target, slink);

        if (add)
                do {
                        _cleanup_close_ int fd = -1;

                        r = mkdir_parents(filename, 0755);
                        if (!IN_SET(r, 0, -ENOENT))
                                break;
                        fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
                        if (fd < 0)
                                r = -errno;
                } while (r == -ENOENT);

        return r;
}
Exemplo n.º 17
0
/* manage "stack of names" with possibly specified device priorities */
static void link_update(struct udev_device *dev, const char *slink, bool add)
{
        struct udev *udev = udev_device_get_udev(dev);
        char name_enc[UTIL_PATH_SIZE];
        char filename[UTIL_PATH_SIZE * 2];
        char dirname[UTIL_PATH_SIZE];
        const char *target;
        char buf[UTIL_PATH_SIZE];

        util_path_encode(slink + strlen("/dev"), name_enc, sizeof(name_enc));
        strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL);
        strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);

        if (!add && unlink(filename) == 0)
                rmdir(dirname);

        target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf));
        if (target == NULL) {
                log_debug("no reference left, remove '%s'", slink);
                if (unlink(slink) == 0)
                        util_delete_path(udev, slink);
        } else {
                log_debug("creating link '%s' to '%s'", slink, target);
                node_symlink(dev, target, slink);
        }

        if (add) {
                int err;

                do {
                        int fd;

                        err = mkdir_parents(filename, 0755);
                        if (err != 0 && err != -ENOENT)
                                break;
                        fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
                        if (fd >= 0)
                                close(fd);
                        else
                                err = -errno;
                } while (err == -ENOENT);
        }
}
Exemplo n.º 18
0
static int process_machine_id(void) {
        const char *etc_machine_id;
        char id[SD_ID128_STRING_MAX];
        int r;

        etc_machine_id = prefix_roota(arg_root, "/etc/machine-id");
        if (laccess(etc_machine_id, F_OK) >= 0)
                return 0;

        if (sd_id128_is_null(arg_machine_id))
                return 0;

        mkdir_parents(etc_machine_id, 0755);
        r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id),
                              WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_SYNC);
        if (r < 0)
                return log_error_errno(r, "Failed to write machine id: %m");

        log_info("%s written.", etc_machine_id);
        return 0;
}
Exemplo n.º 19
0
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
        _cleanup_close_ int fd;
        int r;

        assert(path);

        if (parents)
                mkdir_parents(path, 0755);

        fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
                        (mode == 0 || mode == MODE_INVALID) ? 0644 : mode);
        if (fd < 0)
                return -errno;

        if (mode != MODE_INVALID) {
                r = fchmod(fd, mode);
                if (r < 0)
                        return -errno;
        }

        if (uid != UID_INVALID || gid != GID_INVALID) {
                r = fchown(fd, uid, gid);
                if (r < 0)
                        return -errno;
        }

        if (stamp != USEC_INFINITY) {
                struct timespec ts[2];

                timespec_store(&ts[0], stamp);
                ts[1] = ts[0];
                r = futimens(fd, ts);
        } else
                r = futimens(fd, NULL);
        if (r < 0)
                return -errno;

        return 0;
}
Exemplo n.º 20
0
static int process_hostname(void) {
        const char *etc_hostname;
        int r;

        etc_hostname = prefix_roota(arg_root, "/etc/hostname");
        if (faccessat(AT_FDCWD, etc_hostname, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                return 0;

        r = prompt_hostname();
        if (r < 0)
                return r;

        if (isempty(arg_hostname))
                return 0;

        mkdir_parents(etc_hostname, 0755);
        r = write_string_file(etc_hostname, arg_hostname, WRITE_STRING_FILE_CREATE);
        if (r < 0)
                return log_error_errno(r, "Failed to write %s: %m", etc_hostname);

        log_info("%s written.", etc_hostname);
        return 0;
}
Exemplo n.º 21
0
static void test_copy_tree(void) {
        char original_dir[] = "/tmp/test-copy_tree/";
        char copy_dir[] = "/tmp/test-copy_tree-copy/";
        char **files = STRV_MAKE("file", "dir1/file", "dir1/dir2/file", "dir1/dir2/dir3/dir4/dir5/file");
        char **links = STRV_MAKE("link", "file",
                                 "link2", "dir1/file");
        char **p, **link;
        const char *unixsockp;
        struct stat st;

        log_info("%s", __func__);

        (void) rm_rf(copy_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
        (void) rm_rf(original_dir, REMOVE_ROOT|REMOVE_PHYSICAL);

        STRV_FOREACH(p, files) {
                _cleanup_free_ char *f;

                assert_se(f = strappend(original_dir, *p));

                assert_se(mkdir_parents(f, 0755) >= 0);
                assert_se(write_string_file(f, "file", WRITE_STRING_FILE_CREATE) == 0);
        }
Exemplo n.º 22
0
int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift) {
        _cleanup_free_ char *cgroup = NULL;
        char tree[] = "/tmp/unifiedXXXXXX", pid_string[DECIMAL_STR_MAX(pid) + 1];
        bool undo_mount = false;
        const char *fn;
        int r, unified_controller;

        unified_controller = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
        if (unified_controller < 0)
                return log_error_errno(unified_controller, "Failed to determine whether the systemd hierarchy is unified: %m");
        if ((unified_controller > 0) == (unified_requested >= CGROUP_UNIFIED_SYSTEMD))
                return 0;

        /* When the host uses the legacy cgroup setup, but the
         * container shall use the unified hierarchy, let's make sure
         * we copy the path from the name=systemd hierarchy into the
         * unified hierarchy. Similar for the reverse situation. */

        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup);
        if (r < 0)
                return log_error_errno(r, "Failed to get control group of " PID_FMT ": %m", pid);

        /* In order to access the unified hierarchy we need to mount it */
        if (!mkdtemp(tree))
                return log_error_errno(errno, "Failed to generate temporary mount point for unified hierarchy: %m");

        if (unified_controller > 0)
                r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup",
                                  MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
        else
                r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup2",
                                  MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
        if (r < 0)
                goto finish;

        undo_mount = true;

        /* If nspawn dies abruptly the cgroup hierarchy created below
         * its unit isn't cleaned up. So, let's remove it
         * https://github.com/systemd/systemd/pull/4223#issuecomment-252519810 */
        fn = strjoina(tree, cgroup);
        (void) rm_rf(fn, REMOVE_ROOT|REMOVE_ONLY_DIRECTORIES);

        fn = strjoina(tree, cgroup, "/cgroup.procs");
        (void) mkdir_parents(fn, 0755);

        sprintf(pid_string, PID_FMT, pid);
        r = write_string_file(fn, pid_string, 0);
        if (r < 0) {
                log_error_errno(r, "Failed to move process: %m");
                goto finish;
        }

        fn = strjoina(tree, cgroup);
        r = chown_cgroup_path(fn, uid_shift);
        if (r < 0)
                log_error_errno(r, "Failed to chown() cgroup %s: %m", fn);
finish:
        if (undo_mount)
                (void) umount_verbose(tree);

        (void) rmdir(tree);
        return r;
}
Exemplo n.º 23
0
static int process_root_password(void) {

        static const char table[] =
                "abcdefghijklmnopqrstuvwxyz"
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                "0123456789"
                "./";

        struct spwd item = {
                .sp_namp = (char*) "root",
                .sp_min = -1,
                .sp_max = -1,
                .sp_warn = -1,
                .sp_inact = -1,
                .sp_expire = -1,
                .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
        };

        _cleanup_close_ int lock = -1;
        char salt[3+16+1+1];
        uint8_t raw[16];
        unsigned i;
        char *j;

        const char *etc_shadow;
        int r;

        etc_shadow = prefix_roota(arg_root, "/etc/shadow");
        if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                return 0;

        mkdir_parents(etc_shadow, 0755);

        lock = take_password_lock(arg_root);
        if (lock < 0)
                return lock;

        if (arg_copy_root_password && arg_root) {
                struct spwd *p;

                errno = 0;
                p = getspnam("root");
                if (p || errno != ENOENT) {
                        if (!p) {
                                if (!errno)
                                        errno = EIO;

                                log_error_errno(errno, "Failed to find shadow entry for root: %m");
                                return -errno;
                        }

                        r = write_root_shadow(etc_shadow, p);
                        if (r < 0)
                                return log_error_errno(r, "Failed to write %s: %m", etc_shadow);

                        log_info("%s copied.", etc_shadow);
                        return 0;
                }
        }

        r = prompt_root_password();
        if (r < 0)
                return r;

        if (!arg_root_password)
                return 0;

        r = dev_urandom(raw, 16);
        if (r < 0)
                return log_error_errno(r, "Failed to get salt: %m");

        /* We only bother with SHA512 hashed passwords, the rest is legacy, and we don't do legacy. */
        assert_cc(sizeof(table) == 64 + 1);
        j = stpcpy(salt, "$6$");
        for (i = 0; i < 16; i++)
                j[i] = table[raw[i] & 63];
        j[i++] = '$';
        j[i] = 0;

        errno = 0;
        item.sp_pwdp = crypt(arg_root_password, salt);
        if (!item.sp_pwdp) {
                if (!errno)
                        errno = -EINVAL;

                log_error_errno(errno, "Failed to encrypt password: %m");
                return -errno;
        }

        item.sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);

        r = write_root_shadow(etc_shadow, &item);
        if (r < 0)
                return log_error_errno(r, "Failed to write %s: %m", etc_shadow);

        log_info("%s written.", etc_shadow);
        return 0;
}

static void help(void) {
        printf("%s [OPTIONS...]\n\n"
               "Configures basic settings of the system.\n\n"
               "  -h --help                    Show this help\n"
               "     --version                 Show package version\n"
               "     --root=PATH               Operate on an alternate filesystem root\n"
               "     --locale=LOCALE           Set primary locale (LANG=)\n"
               "     --locale-messages=LOCALE  Set message locale (LC_MESSAGES=)\n"
               "     --timezone=TIMEZONE       Set timezone\n"
               "     --hostname=NAME           Set host name\n"
               "     --machine-ID=ID           Set machine ID\n"
               "     --root-password=PASSWORD  Set root password\n"
               "     --root-password-file=FILE Set root password from file\n"
               "     --prompt-locale           Prompt the user for locale settings\n"
               "     --prompt-timezone         Prompt the user for timezone\n"
               "     --prompt-hostname         Prompt the user for hostname\n"
               "     --prompt-root-password    Prompt the user for root password\n"
               "     --prompt                  Prompt for all of the above\n"
               "     --copy-locale             Copy locale from host\n"
               "     --copy-timezone           Copy timezone from host\n"
               "     --copy-root-password      Copy root password from host\n"
               "     --copy                    Copy locale, timezone, root password\n"
               "     --setup-machine-id        Generate a new random machine ID\n"
               , program_invocation_short_name);
}
Exemplo n.º 24
0
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
        static const struct option options[] = {
                { "update", no_argument, NULL, 'u' },
                { "root", required_argument, NULL, 'r' },
                { "test", required_argument, NULL, 't' },
                { "help", no_argument, NULL, 'h' },
                {}
        };
        const char *test = NULL;
        const char *root = "";
        char *udev_hwdb_path = UDEV_HWDB_BIN;
        bool update = false;
        struct trie *trie = NULL;
        int err;
        int rc = EXIT_SUCCESS;

        for (;;) {
                int option;

                option = getopt_long(argc, argv, "ut:r:h", options, NULL);
                if (option == -1)
                        break;

                switch (option) {
                case 'u':
                        update = true;
                        break;
                case 't':
                        test = optarg;
                        break;
                case 'r':
                        root = optarg;
                        break;
                case 'h':
                        help();
                        return EXIT_SUCCESS;
                }
        }

        if (!update && !test) {
                help();
                return EXIT_SUCCESS;
        }

        if (update) {
                char **files, **f;

                trie = calloc(sizeof(struct trie), 1);
                if (!trie) {
                        rc = EXIT_FAILURE;
                        goto out;
                }

                /* string store */
                trie->strings = strbuf_new();
                if (!trie->strings) {
                        rc = EXIT_FAILURE;
                        goto out;
                }

                /* index */
                trie->root = calloc(sizeof(struct trie_node), 1);
                if (!trie->root) {
                        rc = EXIT_FAILURE;
                        goto out;
                }
                trie->nodes_count++;

                err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs);
                if (err < 0) {
                        log_error("failed to enumerate hwdb files: %s\n", strerror(-err));
                        rc = EXIT_FAILURE;
                        goto out;
                }
                STRV_FOREACH(f, files) {
                        log_debug("reading file '%s'", *f);
                        import_file(udev, trie, *f);
                }
                strv_free(files);

                strbuf_complete(trie->strings);

                log_debug("=== trie in-memory ===\n");
                log_debug("nodes:            %8zu bytes (%8zu)\n",
                          trie->nodes_count * sizeof(struct trie_node), trie->nodes_count);
                log_debug("children arrays:  %8zu bytes (%8zu)\n",
                          trie->children_count * sizeof(struct trie_child_entry), trie->children_count);
                log_debug("values arrays:    %8zu bytes (%8zu)\n",
                          trie->values_count * sizeof(struct trie_value_entry), trie->values_count);
                log_debug("strings:          %8zu bytes\n",
                          trie->strings->len);
                log_debug("strings incoming: %8zu bytes (%8zu)\n",
                          trie->strings->in_len, trie->strings->in_count);
                log_debug("strings dedup'ed: %8zu bytes (%8zu)\n",
                          trie->strings->dedup_len, trie->strings->dedup_count);

                if (root) {
                    if (asprintf(&udev_hwdb_path,
                                 "%s/%s", root, udev_hwdb_path) < 0) {
                        rc = EXIT_FAILURE;
                        goto out;
                    }
                }

                mkdir_parents(udev_hwdb_path, 0755);
                err = trie_store(trie, udev_hwdb_path);

                if (root) {
                    free(udev_hwdb_path);
                }

                if (err < 0) {
                        log_error("Failure writing database %s: %s",
                            udev_hwdb_path, strerror(-err));
                        rc = EXIT_FAILURE;
                }
        }
Exemplo n.º 25
0
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
        static const struct option options[] = {
                { "update", no_argument,       NULL, 'u' },
                { "test",   required_argument, NULL, 't' },
                { "root",   required_argument, NULL, 'r' },
                { "help",   no_argument,       NULL, 'h' },
                {}
        };
        const char *test = NULL;
        const char *root = "";
        bool update = false;
        struct trie *trie = NULL;
        int err, c;
        int rc = EXIT_SUCCESS;

        while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0)
                switch(c) {
                case 'u':
                        update = true;
                        break;
                case 't':
                        test = optarg;
                        break;
                case 'r':
                        root = optarg;
                        break;
                case 'h':
                        help();
                        return EXIT_SUCCESS;
                case '?':
                        return EXIT_FAILURE;
                default:
                        assert_not_reached("Unknown option");
                }

        if (!update && !test) {
                log_error("Either --update or --test must be used");
                return EXIT_FAILURE;
        }

        if (update) {
                char **files, **f;
                _cleanup_free_ char *hwdb_bin = UDEV_HWDB_BIN;

                trie = calloc(sizeof(struct trie), 1);
                if (!trie) {
                        rc = EXIT_FAILURE;
                        goto out;
                }

                /* string store */
                trie->strings = strbuf_new();
                if (!trie->strings) {
                        rc = EXIT_FAILURE;
                        goto out;
                }

                /* index */
                trie->root = calloc(sizeof(struct trie_node), 1);
                if (!trie->root) {
                        rc = EXIT_FAILURE;
                        goto out;
                }
                trie->nodes_count++;

                err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs);
                if (err < 0) {
                        log_error("failed to enumerate hwdb files: %s", strerror(-err));
                        rc = EXIT_FAILURE;
                        goto out;
                }
                STRV_FOREACH(f, files) {
                        log_debug("reading file '%s'", *f);
                        import_file(udev, trie, *f);
                }
                strv_free(files);

                strbuf_complete(trie->strings);

                log_debug("=== trie in-memory ===");
                log_debug("nodes:            %8zu bytes (%8zu)",
                          trie->nodes_count * sizeof(struct trie_node), trie->nodes_count);
                log_debug("children arrays:  %8zu bytes (%8zu)",
                          trie->children_count * sizeof(struct trie_child_entry), trie->children_count);
                log_debug("values arrays:    %8zu bytes (%8zu)",
                          trie->values_count * sizeof(struct trie_value_entry), trie->values_count);
                log_debug("strings:          %8zu bytes",
                          trie->strings->len);
                log_debug("strings incoming: %8zu bytes (%8zu)",
                          trie->strings->in_len, trie->strings->in_count);
                log_debug("strings dedup'ed: %8zu bytes (%8zu)",
                          trie->strings->dedup_len, trie->strings->dedup_count);

                if (asprintf(&hwdb_bin, "%s/%s", root, hwdb_bin) < 0) {
                        rc = EXIT_FAILURE;
                        goto out;
                }
                mkdir_parents(hwdb_bin, 0755);
                err = trie_store(trie, hwdb_bin);
                if (err < 0) {
                        log_error("Failure writing database %s: %s", hwdb_bin, strerror(-err));
                        rc = EXIT_FAILURE;
                }
        }
Exemplo n.º 26
0
static int create_device(void) {
        _cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL, *u_escaped = NULL, *v_escaped = NULL, *root_hash_escaped = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        const char *to;
        int r;

        /* If all three pieces of information are missing, then verity is turned off */
        if (!arg_root_hash && !arg_data_what && !arg_hash_what)
                return 0;

        /* if one of them is missing however, the data is simply incomplete and this is an error */
        if (!arg_root_hash)
                log_error("Verity information incomplete, root hash unspecified.");
        if (!arg_data_what)
                log_error("Verity information incomplete, root data device unspecified.");
        if (!arg_hash_what)
                log_error("Verity information incomplete, root hash device unspecified.");

        if (!arg_root_hash || !arg_data_what || !arg_hash_what)
                return -EINVAL;

        log_debug("Using root verity data device %s,\n"
                  "                  hash device %s,\n"
                  "                and root hash %s.", arg_data_what, arg_hash_what, arg_root_hash);

        u = fstab_node_to_udev_node(arg_data_what);
        if (!u)
                return log_oom();
        v = fstab_node_to_udev_node(arg_hash_what);
        if (!v)
                return log_oom();

        u_escaped = specifier_escape(u);
        if (!u_escaped)
                return log_oom();
        v_escaped = specifier_escape(v);
        if (!v_escaped)
                return log_oom();

        r = unit_name_from_path(u, ".device", &d);
        if (r < 0)
                return log_error_errno(r, "Failed to generate unit name: %m");
        r = unit_name_from_path(v, ".device", &e);
        if (r < 0)
                return log_error_errno(r, "Failed to generate unit name: %m");

        root_hash_escaped = specifier_escape(arg_root_hash);
        if (!root_hash_escaped)
                return log_oom();

        r = generator_open_unit_file(arg_dest, NULL, SYSTEMD_VERITYSETUP_SERVICE, &f);
        if (r < 0)
                return r;

        fprintf(f,
                "[Unit]\n"
                "Description=Integrity Protection Setup for %%I\n"
                "Documentation=man:systemd-veritysetup-generator(8) man:[email protected](8)\n"
                "SourcePath=/proc/cmdline\n"
                "DefaultDependencies=no\n"
                "Conflicts=umount.target\n"
                "BindsTo=%s %s\n"
                "IgnoreOnIsolate=true\n"
                "After=cryptsetup-pre.target %s %s\n"
                "Before=cryptsetup.target umount.target\n"
                "\n[Service]\n"
                "Type=oneshot\n"
                "RemainAfterExit=yes\n"
                "ExecStart=" ROOTLIBEXECDIR "/systemd-veritysetup attach root '%s' '%s' '%s'\n"
                "ExecStop=" ROOTLIBEXECDIR "/systemd-veritysetup detach root\n",
                d, e,
                d, e,
                u_escaped, v_escaped, root_hash_escaped);

        r = fflush_and_check(f);
        if (r < 0)
                return log_error_errno(r, "Failed to write file unit "SYSTEMD_VERITYSETUP_SERVICE": %m");

        to = strjoina(arg_dest, "/cryptsetup.target.requires/" SYSTEMD_VERITYSETUP_SERVICE);

        (void) mkdir_parents(to, 0755);
        if (symlink("../" SYSTEMD_VERITYSETUP_SERVICE, to) < 0)
                return log_error_errno(errno, "Failed to create symlink %s: %m", to);

        return 0;
}
Exemplo n.º 27
0
static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test)
{
        struct udev *udev = udev_device_get_udev(dev);
        static const char *searchpath[] = { FIRMWARE_PATH };
        char fwencpath[UTIL_PATH_SIZE];
        char misspath[UTIL_PATH_SIZE];
        char loadpath[UTIL_PATH_SIZE];
        char datapath[UTIL_PATH_SIZE];
        char fwpath[UTIL_PATH_SIZE];
        const char *firmware;
        FILE *fwfile = NULL;
        struct utsname kernel;
        struct stat statbuf;
        unsigned int i;
        int rc = EXIT_SUCCESS;

        firmware = udev_device_get_property_value(dev, "FIRMWARE");
        if (firmware == NULL) {
                log_error("firmware parameter missing\n\n");
                rc = EXIT_FAILURE;
                goto exit;
        }

        /* lookup firmware file */
        uname(&kernel);
        for (i = 0; i < ELEMENTSOF(searchpath); i++) {
                util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], kernel.release, "/", firmware, NULL);
                fwfile = fopen(fwpath, "re");
                if (fwfile != NULL)
                        break;

                util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], firmware, NULL);
                fwfile = fopen(fwpath, "re");
                if (fwfile != NULL)
                        break;
        }

        util_path_encode(firmware, fwencpath, sizeof(fwencpath));
        util_strscpyl(misspath, sizeof(misspath), "/run/udev/firmware-missing/", fwencpath, NULL);
        util_strscpyl(loadpath, sizeof(loadpath), udev_device_get_syspath(dev), "/loading", NULL);

        if (fwfile == NULL) {
                int err;

                /* This link indicates the missing firmware file and the associated device */
                log_debug("did not find firmware file '%s'\n", firmware);
                do {
                        err = mkdir_parents(misspath, 0755);
                        if (err != 0 && err != -ENOENT)
                                break;
                        err = symlink(udev_device_get_devpath(dev), misspath);
                        if (err != 0)
                                err = -errno;
                } while (err == -ENOENT);
                rc = EXIT_FAILURE;
                /*
                 * Do not cancel the request in the initrd, the real root might have
                 * the firmware file and the 'coldplug' run in the real root will find
                 * this pending request and fulfill or cancel it.
                 * */
                if (!in_initrd())
                        set_loading(udev, loadpath, "-1");
                goto exit;
        }

        if (stat(fwpath, &statbuf) < 0 || statbuf.st_size == 0) {
                if (!in_initrd())
                        set_loading(udev, loadpath, "-1");
                rc = EXIT_FAILURE;
                goto exit;
        }

        if (unlink(misspath) == 0)
                util_delete_path(udev, misspath);

        if (!set_loading(udev, loadpath, "1"))
                goto exit;

        util_strscpyl(datapath, sizeof(datapath), udev_device_get_syspath(dev), "/data", NULL);
        if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
                log_error("error sending firmware '%s' to device\n", firmware);
                set_loading(udev, loadpath, "-1");
                rc = EXIT_FAILURE;
                goto exit;
        };

        set_loading(udev, loadpath, "0");
exit:
        if (fwfile)
                fclose(fwfile);
        return rc;
}
Exemplo n.º 28
0
void fb_table::flush()
{
	char *part_file_path;
	FILE *part_file;
	const char *description = "Generated by ipfixcol fasbit plugin";
	column_writer *writer;
	plain_writer default_writer;

	struct fb_table_header header;
	std::vector<struct fb_column> columns_orig;

	if (!dir) {
		return;
	}

	part_file_path = get_file_path(PART_FILE_NAME);

	MSG_DEBUG(MSG_MODULE, "creating directory '%s'", dir);
	if (!mkdir_parents(dir, 0775)) {
		MSG_ERROR(MSG_MODULE, "failed creating directory %s: %s", dir, strerror(errno));
		delete[] part_file_path;
		return;
	}

	/* first read existing part file */
	part_file = fopen(part_file_path, "r");

	header.name = NULL;
	header.description = NULL;
	header.nrows = 0;
	header.ncolumns = 0;
	if (part_file) {
		parse_part_file(part_file, &header, columns_orig);
		fclose(part_file);
		if (header.description) {
			description = header.description;
		}
	} else {
		MSG_DEBUG(MSG_MODULE, "couldn't open file '%s': %s", part_file_path, strerror(errno));
	}

	/* TODO: check if the original rows match the current ones, otherwise delete the old table */
	/* TODO: proper format of part file */

	part_file = fopen(part_file_path, "w");
	if (part_file == NULL) {
		MSG_WARNING(MSG_MODULE, "couldn't open file '%s': %s", part_file_path, strerror(errno));
		delete[] part_file_path;
		return;
	}
	fprintf(part_file, "# meta data for data partition %u written by ipfixcol fastbit plugin on %s\n\n", template_id, "date");
	fprintf(part_file, "BEGIN HEADER\nName = %u\nDescription = %s\nNumber_of_rows = %lu\nNumber_of_columns = %lu\nTimestamp = %u\nEND HEADER\n", template_id, description, header.nrows + row, ncolumns, 0);

	for (size_t i = 0; i < ncolumns; i++) {
		if (columns[i].type == ibis::UNKNOWN_TYPE) {
			continue;
		}
		char *column_file = this->get_file_path(columns[i].name);

		writer = columns[i].writer;
		if (writer == NULL) {
			writer = &default_writer;
		}

		if (!writer->write(column_file, columns[i].data.get_size(), columns[i].data.access(0))) {
			MSG_ERROR(MSG_MODULE, "failed to write column %s in partition %d", columns[i].name, template_id);
		}
		delete[] column_file;

		// write .sp file for blob columns
		if (columns[i].type == ibis::BLOB) {
			char *sp_filename = this->get_file_path(columns[i].name, ".sp");
			MSG_DEBUG(MSG_MODULE, "wirting .sp file '%d'", sp_filename);
			default_writer.write(sp_filename, columns[i].spfile.get_size(), columns[i].spfile.access(0));
			delete[] sp_filename;
		}

		fprintf(part_file, "\nBegin Column\nname = %s\ndescription = compression: %s\ndata_type = %s\nEnd Column\n", columns[i].name, writer->name, fastbit_type_str(columns[i].type));
		
		
		columns[i].length_prev += columns[i].data.get_size();
		columns[i].row = 0;
		columns[i].data.empty();
		columns[i].spfile.empty();
	}
	fclose(part_file);
	delete[] part_file_path;

	if (header.name) {
		free(header.name);
	}
	if (header.description) {
		free(header.description);
	}

	row = 0;
}
Exemplo n.º 29
0
int generator_write_fsck_deps(
                FILE *f,
                const char *dir,
                const char *what,
                const char *where,
                const char *fstype) {

        int r;

        assert(f);
        assert(dir);
        assert(what);
        assert(where);

        if (!is_device_path(what)) {
                log_warning("Checking was requested for \"%s\", but it is not a device.", what);
                return 0;
        }

        if (!isempty(fstype) && !streq(fstype, "auto")) {
                r = fsck_exists(fstype);
                if (r < 0)
                        log_warning_errno(r, "Checking was requested for %s, but couldn't detect if fsck.%s may be used, proceeding: %m", what, fstype);
                else if (r == 0) {
                        /* treat missing check as essentially OK */
                        log_debug("Checking was requested for %s, but fsck.%s does not exist.", what, fstype);
                        return 0;
                }
        }

        if (path_equal(where, "/")) {
                const char *lnk;

                lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");

                mkdir_parents(lnk, 0755);
                if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0)
                        return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);

        } else {
                _cleanup_free_ char *_fsck = NULL;
                const char *fsck;

                if (in_initrd() && path_equal(where, "/sysroot")) {
                        r = write_fsck_sysroot_service(dir, what);
                        if (r < 0)
                                return r;

                        fsck = "systemd-fsck-root.service";
                } else {
                        r = unit_name_from_path_instance("systemd-fsck", what, ".service", &_fsck);
                        if (r < 0)
                                return log_error_errno(r, "Failed to create fsck service name: %m");

                        fsck = _fsck;
                }

                fprintf(f,
                        "Requires=%1$s\n"
                        "After=%1$s\n",
                        fsck);
        }

        return 0;
}
Exemplo n.º 30
0
                char c[l+1];

                memcpy(c, word, l);
                c[l] = 0;

                if (!GREEDY_REALLOC(uids, sz, n_uids+1))
                        return log_oom();

                r = parse_uid(c, &uids[n_uids++]);
                if (r < 0) {
                        log_error("Failed to parse group data from getent.");
                        return -EIO;
                }
        }

        r = mkdir_parents(home, 0775);
        if (r < 0)
                return log_error_errno(r, "Failed to make home root directory: %m");

        r = mkdir_safe(home, 0755, uid, gid);
        if (r < 0 && r != -EEXIST)
                return log_error_errno(r, "Failed to make home directory: %m");

        (void) fchown(STDIN_FILENO, uid, gid);
        (void) fchown(STDOUT_FILENO, uid, gid);
        (void) fchown(STDERR_FILENO, uid, gid);

        if (setgroups(n_uids, uids) < 0)
                return log_error_errno(errno, "Failed to set auxiliary groups: %m");

        if (setresgid(gid, gid, gid) < 0)