X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fsysusers%2Fsysusers.c;h=19568adf7a820581171b7ce723c8616ca175bafb;hp=129493a1e7ad5779410064dc277db49c9824550d;hb=e70bc43cdf75b36e7ad3d29e9a6f8ee1461e7d5e;hpb=38c74dad1c3d605018e61074e0b80f6b9523b1c8 diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 129493a1e..19568adf7 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -35,6 +35,8 @@ #include "conf-files.h" #include "copy.h" #include "utf8.h" +#include "label.h" +#include "fileio-label.h" typedef enum ItemType { ADD_USER = 'u', @@ -62,6 +64,8 @@ typedef struct Item { static char *arg_root = NULL; static const char conf_file_dirs[] = + "/etc/sysusers.d\0" + "/run/sysusers.d\0" "/usr/local/lib/sysusers.d\0" "/usr/lib/sysusers.d\0" #ifdef HAVE_SPLIT_USR @@ -191,8 +195,9 @@ static int load_group_database(void) { return 0; } -static int make_backup(const char *x) { - _cleanup_close_ int src = -1, dst = -1; +static int make_backup(const char *target, const char *x) { + _cleanup_close_ int src = -1; + _cleanup_fclose_ FILE *dst = NULL; char *backup, *temp; struct timespec ts[2]; struct stat st; @@ -209,30 +214,30 @@ static int make_backup(const char *x) { if (fstat(src, &st) < 0) return -errno; - temp = strappenda(x, ".XXXXXX"); - dst = mkostemp_safe(temp, O_WRONLY|O_CLOEXEC|O_NOCTTY); - if (dst < 0) - return dst; + r = fopen_temporary_label(target, x, &dst, &temp); + if (r < 0) + return r; - r = copy_bytes(src, dst, (off_t) -1); + r = copy_bytes(src, fileno(dst), (off_t) -1); if (r < 0) goto fail; + /* Don't fail on chmod() or chown(). If it stays owned by us + * and/or unreadable by others, then it isn't too bad... */ + + backup = strappenda(x, "-"); + /* Copy over the access mask */ - if (fchmod(dst, st.st_mode & 07777) < 0) { - r = -errno; - goto fail; - } + if (fchmod(fileno(dst), st.st_mode & 07777) < 0) + log_warning("Failed to change mode on %s: %m", backup); - /* Don't fail on chmod(). If it stays owned by us, then it - * isn't too bad... */ - fchown(dst, st.st_uid, st.st_gid); + if (fchown(fileno(dst), st.st_uid, st.st_gid)< 0) + log_warning("Failed to change ownership of %s: %m", backup); ts[0] = st.st_atim; ts[1] = st.st_mtim; - futimens(dst, ts); + futimens(fileno(dst), ts); - backup = strappenda(x, "-"); if (rename(temp, backup) < 0) goto fail; @@ -310,7 +315,7 @@ static int write_files(void) { _cleanup_fclose_ FILE *original = NULL; group_path = fix_root("/etc/group"); - r = fopen_temporary(group_path, &group, &group_tmp); + r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp); if (r < 0) goto finish; @@ -386,7 +391,7 @@ static int write_files(void) { _cleanup_fclose_ FILE *original = NULL; passwd_path = fix_root("/etc/passwd"); - r = fopen_temporary(passwd_path, &passwd, &passwd_tmp); + r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp); if (r < 0) goto finish; @@ -465,13 +470,13 @@ static int write_files(void) { /* Make a backup of the old files */ if (group && group_changed) { - r = make_backup(group_path); + r = make_backup("/etc/group", group_path); if (r < 0) goto finish; } if (passwd) { - r = make_backup(passwd_path); + r = make_backup("/etc/passwd", passwd_path); if (r < 0) goto finish; } @@ -1408,16 +1413,13 @@ static void free_database(Hashmap *by_name, Hashmap *by_id) { hashmap_free(by_id); } -static int help(void) { - +static void help(void) { printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" "Creates system user accounts.\n\n" " -h --help Show this help\n" " --version Show package version\n" - " --root=PATH Operate on an alternate filesystem root\n", - program_invocation_short_name); - - return 0; + " --root=PATH Operate on an alternate filesystem root\n" + , program_invocation_short_name); } static int parse_argv(int argc, char *argv[]) { @@ -1439,12 +1441,13 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': - return help(); + help(); + return 0; case ARG_VERSION: puts(PACKAGE_STRING); @@ -1466,7 +1469,6 @@ static int parse_argv(int argc, char *argv[]) { default: assert_not_reached("Unhandled option"); } - } return 1; } @@ -1489,7 +1491,11 @@ int main(int argc, char *argv[]) { umask(0022); - r = 0; + r = label_init(NULL); + if (r < 0) { + log_error("SELinux setup failed: %s", strerror(-r)); + goto finish; + } if (optind < argc) { int j;