mirror of
https://github.com/SELinuxProject/selinux
synced 2025-03-09 11:47:39 +00:00
restorecon and symbolic links
Based on a patch by Martin Orr. Restore the code to compute the realpath of all but the last component of a symlink, and relabel both the symlink and (if it exists) the target of the symlink when a symlink is specified to restorecon. Thus, restorecon -R /etc/init.d will restore both the /etc/init.d symlink context and the directory tree starting from /etc/rc.d/init.d. This fixes the restorecon /dev/stdin performed by the Debian udev init script that was broken by policycoreutils 2.0.70. [sds: switched use of _realpath suffix for process_one, and dropped warning on non-existent target] Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
This commit is contained in:
parent
206e2dfe7a
commit
cc45b9a237
@ -545,7 +545,47 @@ int canoncon(char **contextp)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int process_one(char *name)
|
||||
static int symlink_realpath(char *name, char *path)
|
||||
{
|
||||
char *p = NULL, *file_sep;
|
||||
char *tmp_path = strdupa(name);
|
||||
size_t len = 0;
|
||||
|
||||
if (!tmp_path) {
|
||||
fprintf(stderr, "strdupa on %s failed: %s\n", name,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
file_sep = strrchr(tmp_path, '/');
|
||||
if (file_sep == tmp_path) {
|
||||
file_sep++;
|
||||
p = strcpy(path, "");
|
||||
} else if (file_sep) {
|
||||
*file_sep = 0;
|
||||
file_sep++;
|
||||
p = realpath(tmp_path, path);
|
||||
} else {
|
||||
file_sep = tmp_path;
|
||||
p = realpath("./", path);
|
||||
}
|
||||
if (p)
|
||||
len = strlen(p);
|
||||
if (!p || len + strlen(file_sep) + 2 > PATH_MAX) {
|
||||
fprintf(stderr, "symlink_realpath(%s) failed %s\n", name,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
p += len;
|
||||
/* ensure trailing slash of directory name */
|
||||
if (len == 0 || *(p - 1) != '/') {
|
||||
*p = '/';
|
||||
p++;
|
||||
}
|
||||
strcpy(p, file_sep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_one(char *name, int recurse_this_path)
|
||||
{
|
||||
int rc = 0;
|
||||
const char *namelist[2];
|
||||
@ -553,18 +593,6 @@ static int process_one(char *name)
|
||||
FTS *fts_handle;
|
||||
FTSENT *ftsent;
|
||||
|
||||
if (expand_realpath) {
|
||||
char *p;
|
||||
p = realpath(name, NULL);
|
||||
if (!p) {
|
||||
fprintf(stderr, "realpath(%s) failed %s\n", name,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
name = p;
|
||||
}
|
||||
|
||||
|
||||
if (!strcmp(name, "/"))
|
||||
mass_relabel = 1;
|
||||
|
||||
@ -604,7 +632,7 @@ static int process_one(char *name)
|
||||
fts_set(fts_handle, ftsent, FTS_SKIP);
|
||||
if (rc == ERR)
|
||||
goto err;
|
||||
if (!recurse)
|
||||
if (!recurse_this_path)
|
||||
break;
|
||||
} while ((ftsent = fts_read(fts_handle)) != NULL);
|
||||
|
||||
@ -619,8 +647,6 @@ out:
|
||||
}
|
||||
if (fts_handle)
|
||||
fts_close(fts_handle);
|
||||
if (expand_realpath)
|
||||
free(name);
|
||||
return rc;
|
||||
|
||||
err:
|
||||
@ -630,6 +656,52 @@ err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int process_one_realpath(char *name)
|
||||
{
|
||||
int rc = 0;
|
||||
char *p;
|
||||
struct stat sb;
|
||||
|
||||
if (!expand_realpath) {
|
||||
return process_one(name, recurse);
|
||||
} else {
|
||||
rc = lstat(name, &sb);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: lstat(%s) failed: %s\n",
|
||||
progname, name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (S_ISLNK(sb.st_mode)) {
|
||||
char path[PATH_MAX + 1];
|
||||
|
||||
rc = symlink_realpath(name, path);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = process_one(path, 0);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
p = realpath(name, NULL);
|
||||
if (p) {
|
||||
rc = process_one(p, recurse);
|
||||
free(p);
|
||||
}
|
||||
return rc;
|
||||
} else {
|
||||
p = realpath(name, NULL);
|
||||
if (!p) {
|
||||
fprintf(stderr, "realpath(%s) failed %s\n", name,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
rc = process_one(p, recurse);
|
||||
free(p);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_AUDIT
|
||||
static void maybe_audit_mass_relabel(void)
|
||||
{
|
||||
@ -987,13 +1059,13 @@ int main(int argc, char **argv)
|
||||
delim = (null_terminated != 0) ? '\0' : '\n';
|
||||
while ((len = getdelim(&buf, &buf_len, delim, f)) > 0) {
|
||||
buf[len - 1] = 0;
|
||||
errors |= process_one(buf);
|
||||
errors |= process_one_realpath(buf);
|
||||
}
|
||||
if (strcmp(input_filename, "-") != 0)
|
||||
fclose(f);
|
||||
} else {
|
||||
for (i = optind; i < argc; i++) {
|
||||
errors |= process_one(argv[i]);
|
||||
errors |= process_one_realpath(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user