summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--src/ls.c72
2 files changed, 50 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index a8cfcb3c1..c4940da3d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2007-12-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ "ls -l" wouldn't output "+" on SELinux hosts unless -Z was also given.
+ * src/ls.c (gobble_file): Also get the file context if -l is specified.
+ Treat getfilecon failures like file_has_acl failures.
+ (UNKNOWN_SECURITY_CONTEXT): New constant.
+ (clear_files): Don't free it.
+ (gobble_file): Set unknown security contexts to it; that way, we
+ don't have to have special cases for unknown contexts.
+ (print_long_format, print_file_name_and_frills): Don't worry
+ about scontext being null, since it's always some string now.
+
2007-12-11 Jim Meyering <meyering@redhat.com>
* NEWS: Add the "Bug fixes" heading.
diff --git a/src/ls.c b/src/ls.c
index 946e71169..83fac90d4 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -315,6 +315,7 @@ static time_t current_time = TYPE_MINIMUM (time_t);
static int current_time_ns = -1;
static bool print_scontext;
+static char UNKNOWN_SECURITY_CONTEXT[] = "?";
/* Whether any of the files has an ACL. This affects the width of the
mode column. */
@@ -2516,11 +2517,8 @@ clear_files (void)
struct fileinfo *f = sorted_file[i];
free (f->name);
free (f->linkname);
- if (f->scontext)
- {
- freecon (f->scontext);
- f->scontext = NULL;
- }
+ if (f->scontext != UNKNOWN_SECURITY_CONTEXT)
+ freecon (f->scontext);
}
cwd_n_used = 0;
@@ -2594,8 +2592,6 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
)))))
{
- /* FIXME-c99: move this decl "down", once ls.c stabilizes. */
- bool file_has_security_context = false;
/* Absolute name of this file. */
char *absolute_name;
bool do_deref;
@@ -2645,23 +2641,6 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
break;
}
- if (err == 0 && print_scontext)
- {
- int attr_len = (do_deref
- ? getfilecon (absolute_name, &f->scontext)
- : lgetfilecon (absolute_name, &f->scontext));
- err = (attr_len < 0);
- file_has_security_context =
- (err == 0 && ! STREQ ("unlabeled", f->scontext));
-
- /* When requesting security context information, don't make
- ls fail just because the file (even a command line argument)
- isn't on the right type of file system. I.e., a getfilecon
- failure isn't in the same class as a stat failure. */
- if (err && (errno == ENOTSUP || errno == ENODATA))
- err = 0;
- }
-
if (err != 0)
{
/* Failure to stat a command line argument leads to
@@ -2680,12 +2659,39 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
f->stat_ok = true;
- if (format == long_format)
+ if (format == long_format || print_scontext)
{
- int n = file_has_acl (absolute_name, &f->stat);
- f->have_acl = (0 < n || file_has_security_context);
- any_has_acl |= f->have_acl;
- if (n < 0)
+ bool have_acl = false;
+ int attr_len = (do_deref
+ ? getfilecon (absolute_name, &f->scontext)
+ : lgetfilecon (absolute_name, &f->scontext));
+ err = (attr_len < 0);
+
+ if (err == 0)
+ have_acl = ! STREQ ("unlabeled", f->scontext);
+ else
+ {
+ f->scontext = UNKNOWN_SECURITY_CONTEXT;
+
+ /* When requesting security context information, don't make
+ ls fail just because the file (even a command line argument)
+ isn't on the right type of file system. I.e., a getfilecon
+ failure isn't in the same class as a stat failure. */
+ if (errno == ENOTSUP || errno == ENODATA)
+ err = 0;
+ }
+
+ if (err == 0 && ! have_acl && format == long_format)
+ {
+ int n = file_has_acl (absolute_name, &f->stat);
+ err = (n < 0);
+ have_acl = (0 < n);
+ }
+
+ f->have_acl = have_acl;
+ any_has_acl |= have_acl;
+
+ if (err)
error (0, errno, "%s", quotearg_colon (absolute_name));
}
@@ -2775,7 +2781,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
if (print_scontext)
{
- int len = f->scontext ? strlen (f->scontext) : 0;
+ int len = strlen (f->scontext);
if (scontext_width < len)
scontext_width = len;
}
@@ -3520,8 +3526,7 @@ print_long_format (const struct fileinfo *f)
format_user (f->stat.st_author, author_width, f->stat_ok);
if (print_scontext)
- format_user_or_group ((f->scontext ? f->scontext : "?"),
- 0, scontext_width);
+ format_user_or_group (f->scontext, 0, scontext_width);
p = buf;
}
@@ -3860,8 +3865,7 @@ print_file_name_and_frills (const struct fileinfo *f)
ST_NBLOCKSIZE, output_block_size));
if (print_scontext)
- printf ("%*s ", format == with_commas ? 0 : scontext_width,
- (f->scontext ? f->scontext : "?"));
+ printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
f->stat_ok, f->filetype, NULL);