diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c index b649d8f..f8bd950 100644 --- a/policycoreutils/setfiles/restore.c +++ b/policycoreutils/setfiles/restore.c @@ -1,4 +1,5 @@ #include "restore.h" +#include #define SKIP -2 #define ERR -1 @@ -31,7 +32,6 @@ struct edir { static file_spec_t *fl_head; -static int exclude(const char *file); static int filespec_add(ino_t ino, const security_context_t con, const char *file); static int only_changed_user(const char *a, const char *b); struct restore_opts *r_opts = NULL; @@ -53,7 +53,6 @@ void remove_exclude(const char *directory) } } return; - } void restore_init(struct restore_opts *opts) @@ -300,8 +299,14 @@ static int process_one(char *name, int recurse_this_path) int rc = 0; const char *namelist[2] = {name, NULL}; dev_t dev_num = 0; - FTS *fts_handle; - FTSENT *ftsent; + FTS *fts_handle = NULL; + FTSENT *ftsent = NULL; + + if (r_opts == NULL){ + fprintf(stderr, + "Must call initialize first!"); + goto err; + } fts_handle = fts_open((char **)namelist, r_opts->fts_flags, NULL); if (fts_handle == NULL) { @@ -357,6 +362,29 @@ err: goto out; } +int process_glob(char *name, int recurse) { + glob_t globbuf; + size_t i = 0; + int errors = 0; + memset(&globbuf, 0, sizeof(globbuf)); + globbuf.gl_offs = 0; + if (glob(name, + GLOB_TILDE | GLOB_PERIOD, + NULL, + &globbuf) >= 0) { + for (i = 0; i < globbuf.gl_pathc; i++) { + int len = strlen(globbuf.gl_pathv[i]) -2; + if (len > 0 && strcmp(&globbuf.gl_pathv[i][len--], "/.") == 0) continue; + if (len > 0 && strcmp(&globbuf.gl_pathv[i][len], "/..") == 0) continue; + errors |= process_one_realpath(globbuf.gl_pathv[i], recurse) < 0; + } + globfree(&globbuf); + } + else + errors |= process_one_realpath(name, recurse) < 0; + return errors; +} + int process_one_realpath(char *name, int recurse) { int rc = 0; @@ -374,6 +402,7 @@ int process_one_realpath(char *name, int recurse) } else { rc = lstat(name, &sb); if (rc < 0) { + if (r_opts->ignore_enoent && errno == ENOENT) return 0; fprintf(stderr, "%s: lstat(%s) failed: %s\n", r_opts->progname, name, strerror(errno)); return -1; @@ -409,7 +438,7 @@ int process_one_realpath(char *name, int recurse) } } -static int exclude(const char *file) +int exclude(const char *file) { int i = 0; for (i = 0; i < excludeCtr; i++) { @@ -602,5 +631,67 @@ static int filespec_add(ino_t ino, const security_context_t con, const char *fil return -1; } +#include +/* + Search /proc/mounts for all file systems that do not support extended + attributes and add them to the exclude directory table. File systems + that support security labels have the seclabel option. +*/ +void exclude_non_seclabel_mounts() +{ + struct utsname uts; + FILE *fp; + size_t len; + ssize_t num; + int index = 0, found = 0; + char *mount_info[4]; + char *buf = NULL, *item; + + /* Check to see if the kernel supports seclabel */ + if (uname(&uts) == 0 && strverscmp(uts.release, "2.6.30") < 0) + return; + if (is_selinux_enabled() <= 0) + return; + + fp = fopen("/proc/mounts", "r"); + if (!fp) + return; + + while ((num = getline(&buf, &len, fp)) != -1) { + found = 0; + index = 0; + item = strtok(buf, " "); + while (item != NULL) { + mount_info[index] = item; + if (index == 3) + break; + index++; + item = strtok(NULL, " "); + } + if (index < 3) { + fprintf(stderr, + "/proc/mounts record \"%s\" has incorrect format.\n", + buf); + continue; + } + /* remove pre-existing entry */ + remove_exclude(mount_info[1]); + + item = strtok(mount_info[3], ","); + while (item != NULL) { + if (strcmp(item, "seclabel") == 0) { + found = 1; + break; + } + item = strtok(NULL, ","); + } + + /* exclude mount points without the seclabel option */ + if (!found) + add_exclude(mount_info[1]); + } + + free(buf); +} diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h index 03b82e8..8b50ff8 100644 --- a/policycoreutils/setfiles/restore.h +++ b/policycoreutils/setfiles/restore.h @@ -27,6 +27,7 @@ struct restore_opts { int hard_links; int verbose; int logging; + int ignore_enoent; char *rootpath; int rootpathlen; char *progname; @@ -44,7 +45,10 @@ struct restore_opts { void restore_init(struct restore_opts *opts); void restore_finish(); int add_exclude(const char *directory); +int exclude(const char *path); void remove_exclude(const char *directory); int process_one_realpath(char *name, int recurse); +int process_glob(char *name, int recurse); +void exclude_non_seclabel_mounts(); #endif diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8 index 1eb6a43..c8ea4bb 100644 --- a/policycoreutils/setfiles/restorecon.8 +++ b/policycoreutils/setfiles/restorecon.8 @@ -4,10 +4,10 @@ restorecon \- restore file(s) default SELinux security contexts. .SH "SYNOPSIS" .B restorecon -.I [\-o outfilename ] [\-R] [\-n] [\-v] [\-e directory ] pathname... +.I [\-o outfilename ] [\-R] [\-n] [\-p] [\-v] [\-e directory ] pathname... .P .B restorecon -.I \-f infilename [\-o outfilename ] [\-e directory ] [\-R] [\-n] [\-v] [\-F] +.I \-f infilename [\-o outfilename ] [\-e directory ] [\-R] [\-n] [\-p] [\-v] [\-F] .SH "DESCRIPTION" This manual page describes the @@ -40,6 +40,9 @@ don't change any file labels. .TP .B \-o outfilename save list of files with incorrect context in outfilename. +.TP +.B \-p +show progress by printing * every 1000 files. .TP .B \-v show changes in file labels. diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 index ac68b94..28f99d9 100644 --- a/policycoreutils/setfiles/setfiles.8 +++ b/policycoreutils/setfiles/setfiles.8 @@ -31,6 +31,9 @@ log changes in file labels to syslog. .TP .B \-n don't change any file labels. +.TP +.B \-p +show progress by printing * every 1000 files. .TP .B \-q suppress non-error output. diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c index 8f4f663..b0a7e09 100644 --- a/policycoreutils/setfiles/setfiles.c +++ b/policycoreutils/setfiles/setfiles.c @@ -5,7 +5,6 @@ #include #include #include -#include #define __USE_XOPEN_EXTENDED 1 /* nftw */ #include #ifdef USE_AUDIT @@ -25,7 +24,6 @@ static char *policyfile = NULL; static int warn_no_match = 0; static int null_terminated = 0; static int errors; -static int ignore_enoent; static struct restore_opts r_opts; #define STAT_BLOCK_SIZE 1 @@ -44,13 +42,13 @@ void usage(const char *const name) { if (iamrestorecon) { fprintf(stderr, - "usage: %s [-iFnrRv0] [-e excludedir ] [-o filename ] [-f filename | pathname... ]\n", + "usage: %s [-iFnprRv0] [-e excludedir ] [-o filename ] [-f filename | pathname... ]\n", name); } else { fprintf(stderr, "usage: %s [-dnpqvW] [-o filename] [-r alt_root_path ] spec_file pathname...\n" "usage: %s -c policyfile spec_file\n" - "usage: %s -s [-dnqvW] [-o filename ] spec_file\n", name, name, + "usage: %s -s [-dnpqvW] [-o filename ] spec_file\n", name, name, name); } exit(1); @@ -138,69 +136,6 @@ static void maybe_audit_mass_relabel(void) #endif } -/* - Search /proc/mounts for all file systems that do not support extended - attributes and add them to the exclude directory table. File systems - that support security labels have the seclabel option. -*/ -static void exclude_non_seclabel_mounts() -{ - struct utsname uts; - FILE *fp; - size_t len; - ssize_t num; - int index = 0, found = 0; - char *mount_info[4]; - char *buf = NULL, *item; - - /* Check to see if the kernel supports seclabel */ - if (uname(&uts) == 0 && strverscmp(uts.release, "2.6.30") < 0) - return; - if (is_selinux_enabled() <= 0) - return; - - fp = fopen("/proc/mounts", "r"); - if (!fp) - return; - - while ((num = getline(&buf, &len, fp)) != -1) { - found = 0; - index = 0; - item = strtok(buf, " "); - while (item != NULL) { - mount_info[index] = item; - if (index == 3) - break; - index++; - item = strtok(NULL, " "); - } - if (index < 3) { - fprintf(stderr, - "/proc/mounts record \"%s\" has incorrect format.\n", - buf); - continue; - } - - /* remove pre-existing entry */ - remove_exclude(mount_info[1]); - - item = strtok(mount_info[3], ","); - while (item != NULL) { - if (strcmp(item, "seclabel") == 0) { - found = 1; - break; - } - item = strtok(NULL, ","); - } - - /* exclude mount points without the seclabel option */ - if (!found) - add_exclude(mount_info[1]); - } - - free(buf); -} - int main(int argc, char **argv) { struct stat sb; @@ -335,7 +270,7 @@ int main(int argc, char **argv) r_opts.debug = 1; break; case 'i': - ignore_enoent = 1; + r_opts.ignore_enoent = 1; break; case 'l': r_opts.logging = 1; @@ -371,7 +306,7 @@ int main(int argc, char **argv) break; } if (optind + 1 >= argc) { - fprintf(stderr, "usage: %s -r r_opts.rootpath\n", + fprintf(stderr, "usage: %s -r rootpath\n", argv[0]); exit(1); } @@ -475,7 +410,7 @@ int main(int argc, char **argv) buf[len - 1] = 0; if (!strcmp(buf, "/")) mass_relabel = 1; - errors |= process_one_realpath(buf, recurse) < 0; + errors |= process_glob(buf, recurse) < 0; } if (strcmp(input_filename, "-") != 0) fclose(f); @@ -483,7 +418,8 @@ int main(int argc, char **argv) for (i = optind; i < argc; i++) { if (!strcmp(argv[i], "/")) mass_relabel = 1; - errors |= process_one_realpath(argv[i], recurse) < 0; + + errors |= process_glob(argv[i], recurse) < 0; } }