|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
File: setfacl.c
|
|
rpm-build |
0a0c83 |
(Linux Access Control List Management)
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
Copyright (C) 1999-2002
|
|
rpm-build |
0a0c83 |
Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is free software; you can redistribute it and/or
|
|
rpm-build |
0a0c83 |
modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License as published by the Free Software Foundation; either
|
|
rpm-build |
0a0c83 |
version 2.1 of the License, or (at your option) any later version.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is distributed in the hope that it will be useful,
|
|
rpm-build |
0a0c83 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0a0c83 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0a0c83 |
Lesser General Public License for more details.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License along with this library; if not, write to the Free Software
|
|
rpm-build |
0a0c83 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#include "config.h"
|
|
rpm-build |
0a0c83 |
#include <limits.h>
|
|
rpm-build |
0a0c83 |
#include <stdio.h>
|
|
rpm-build |
0a0c83 |
#include <string.h>
|
|
rpm-build |
0a0c83 |
#include <unistd.h>
|
|
rpm-build |
0a0c83 |
#include <errno.h>
|
|
rpm-build |
0a0c83 |
#include <sys/stat.h>
|
|
rpm-build |
0a0c83 |
#include <dirent.h>
|
|
rpm-build |
0a0c83 |
#include <libgen.h>
|
|
rpm-build |
0a0c83 |
#include <getopt.h>
|
|
rpm-build |
0a0c83 |
#include "misc.h"
|
|
rpm-build |
0a0c83 |
#include "sequence.h"
|
|
rpm-build |
0a0c83 |
#include "parse.h"
|
|
rpm-build |
0a0c83 |
#include "do_set.h"
|
|
rpm-build |
0a0c83 |
#include "walk_tree.h"
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define POSIXLY_CORRECT_STR "POSIXLY_CORRECT"
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* '-' stands for `process non-option arguments in loop' */
|
|
rpm-build |
0a0c83 |
#if !POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
# define CMD_LINE_OPTIONS "-:bkndvhm:M:x:X:RLP"
|
|
rpm-build |
0a0c83 |
# define CMD_LINE_SPEC "[-bkndRLP] { -m|-M|-x|-X ... } file ..."
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
#define POSIXLY_CMD_LINE_OPTIONS "-:bkndvhm:M:x:X:"
|
|
rpm-build |
0a0c83 |
#define POSIXLY_CMD_LINE_SPEC "[-bknd] {-m|-M|-x|-X ... } file ..."
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
struct option long_options[] = {
|
|
rpm-build |
0a0c83 |
#if !POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
{ "set", 1, 0, 's' },
|
|
rpm-build |
0a0c83 |
{ "set-file", 1, 0, 'S' },
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
{ "mask", 0, 0, 'r' },
|
|
rpm-build |
0a0c83 |
{ "recursive", 0, 0, 'R' },
|
|
rpm-build |
0a0c83 |
{ "logical", 0, 0, 'L' },
|
|
rpm-build |
0a0c83 |
{ "physical", 0, 0, 'P' },
|
|
rpm-build |
0a0c83 |
{ "restore", 1, 0, 'B' },
|
|
rpm-build |
0a0c83 |
{ "test", 0, 0, 't' },
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
{ "modify", 1, 0, 'm' },
|
|
rpm-build |
0a0c83 |
{ "modify-file", 1, 0, 'M' },
|
|
rpm-build |
0a0c83 |
{ "remove", 1, 0, 'x' },
|
|
rpm-build |
0a0c83 |
{ "remove-file", 1, 0, 'X' },
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
{ "default", 0, 0, 'd' },
|
|
rpm-build |
0a0c83 |
{ "no-mask", 0, 0, 'n' },
|
|
rpm-build |
0a0c83 |
{ "remove-all", 0, 0, 'b' },
|
|
rpm-build |
0a0c83 |
{ "remove-default", 0, 0, 'k' },
|
|
rpm-build |
0a0c83 |
{ "version", 0, 0, 'v' },
|
|
rpm-build |
0a0c83 |
{ "help", 0, 0, 'h' },
|
|
rpm-build |
0a0c83 |
{ NULL, 0, 0, 0 },
|
|
rpm-build |
0a0c83 |
};
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
const char *progname;
|
|
rpm-build |
0a0c83 |
const char *cmd_line_options, *cmd_line_spec;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
int walk_flags = WALK_TREE_DEREFERENCE_TOPLEVEL;
|
|
rpm-build |
0a0c83 |
int opt_recalculate; /* recalculate mask entry (0=default, 1=yes, -1=no) */
|
|
rpm-build |
0a0c83 |
int opt_promote; /* promote access ACL to default ACL */
|
|
rpm-build |
0a0c83 |
int opt_test; /* do not write to the file system.
|
|
rpm-build |
0a0c83 |
Print what would happen instead. */
|
|
rpm-build |
0a0c83 |
#if POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
const int posixly_correct = 1; /* Posix compatible behavior! */
|
|
rpm-build |
0a0c83 |
#else
|
|
rpm-build |
0a0c83 |
int posixly_correct; /* Posix compatible behavior? */
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
int chown_error;
|
|
rpm-build |
0a0c83 |
int promote_warning;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static const char *xquote(const char *str, const char *quote_chars)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
const char *q = __acl_quote(str, quote_chars);
|
|
rpm-build |
0a0c83 |
if (q == NULL) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, "%s: %s\n", progname, strerror(errno));
|
|
rpm-build |
0a0c83 |
exit(1);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return q;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
int
|
|
rpm-build |
0a0c83 |
has_any_of_type(
|
|
rpm-build |
0a0c83 |
cmd_t cmd,
|
|
rpm-build |
0a0c83 |
acl_type_t acl_type)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
while (cmd) {
|
|
rpm-build |
0a0c83 |
if (cmd->c_type == acl_type)
|
|
rpm-build |
0a0c83 |
return 1;
|
|
rpm-build |
0a0c83 |
cmd = cmd->c_next;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if !POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
int
|
|
rpm-build |
0a0c83 |
restore(
|
|
rpm-build |
0a0c83 |
FILE *file,
|
|
rpm-build |
0a0c83 |
const char *filename)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
char *path_p;
|
|
rpm-build |
0a0c83 |
struct stat st;
|
|
rpm-build |
0a0c83 |
uid_t uid;
|
|
rpm-build |
0a0c83 |
gid_t gid;
|
|
rpm-build |
0a0c83 |
mode_t mask, flags;
|
|
rpm-build |
0a0c83 |
struct do_set_args args = { };
|
|
rpm-build |
0a0c83 |
int lineno = 0, backup_line;
|
|
rpm-build |
0a0c83 |
int error, status = 0;
|
|
rpm-build |
0a0c83 |
int chmod_required = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
memset(&st, 0, sizeof(st));
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
for(;;) {
|
|
rpm-build |
0a0c83 |
backup_line = lineno;
|
|
rpm-build |
0a0c83 |
error = read_acl_comments(file, &lineno, &path_p, &uid, &gid,
|
|
rpm-build |
0a0c83 |
&flags);
|
|
rpm-build |
0a0c83 |
if (error < 0) {
|
|
rpm-build |
0a0c83 |
error = -error;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (error == 0)
|
|
rpm-build |
0a0c83 |
return status;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (path_p == NULL) {
|
|
rpm-build |
0a0c83 |
if (filename) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("%s: %s: No filename found "
|
|
rpm-build |
0a0c83 |
"in line %d, aborting\n"),
|
|
rpm-build |
0a0c83 |
progname, xquote(filename, "\n\r"),
|
|
rpm-build |
0a0c83 |
backup_line);
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("%s: No filename found in "
|
|
rpm-build |
0a0c83 |
"line %d of standard input, "
|
|
rpm-build |
0a0c83 |
"aborting\n"),
|
|
rpm-build |
0a0c83 |
progname, backup_line);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
status = 1;
|
|
rpm-build |
0a0c83 |
goto getout;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (!(args.seq = seq_init()))
|
|
rpm-build |
0a0c83 |
goto fail_errno;
|
|
rpm-build |
0a0c83 |
if (seq_append_cmd(args.seq, CMD_REMOVE_ACL, ACL_TYPE_ACCESS) ||
|
|
rpm-build |
0a0c83 |
seq_append_cmd(args.seq, CMD_REMOVE_ACL, ACL_TYPE_DEFAULT))
|
|
rpm-build |
0a0c83 |
goto fail_errno;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
error = read_acl_seq(file, args.seq, CMD_ENTRY_REPLACE,
|
|
rpm-build |
0a0c83 |
SEQ_PARSE_WITH_PERM |
|
|
rpm-build |
0a0c83 |
SEQ_PARSE_DEFAULT |
|
|
rpm-build |
0a0c83 |
SEQ_PARSE_MULTI,
|
|
rpm-build |
0a0c83 |
&lineno, NULL);
|
|
rpm-build |
0a0c83 |
if (error != 0) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("%s: %s: %s in line %d\n"),
|
|
rpm-build |
0a0c83 |
progname, xquote(filename, "\n\r"), strerror(errno),
|
|
rpm-build |
0a0c83 |
lineno);
|
|
rpm-build |
0a0c83 |
status = 1;
|
|
rpm-build |
0a0c83 |
goto getout;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
error = stat(path_p, &st);
|
|
rpm-build |
0a0c83 |
if (opt_test && error != 0) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, "%s: %s: %s\n", progname,
|
|
rpm-build |
0a0c83 |
xquote(path_p, "\n\r"), strerror(errno));
|
|
rpm-build |
0a0c83 |
status = 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
args.mode = 0;
|
|
rpm-build |
0a0c83 |
error = do_set(path_p, &st, 0, &args);
|
|
rpm-build |
0a0c83 |
if (error != 0) {
|
|
rpm-build |
0a0c83 |
status = 1;
|
|
rpm-build |
0a0c83 |
goto resume;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (uid != ACL_UNDEFINED_ID && uid != st.st_uid)
|
|
rpm-build |
0a0c83 |
st.st_uid = uid;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
st.st_uid = -1;
|
|
rpm-build |
0a0c83 |
if (gid != ACL_UNDEFINED_ID && gid != st.st_gid)
|
|
rpm-build |
0a0c83 |
st.st_gid = gid;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
st.st_gid = -1;
|
|
rpm-build |
0a0c83 |
if (!opt_test &&
|
|
rpm-build |
0a0c83 |
(st.st_uid != -1 || st.st_gid != -1)) {
|
|
rpm-build |
0a0c83 |
if (chown(path_p, st.st_uid, st.st_gid) != 0) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("%s: %s: Cannot change "
|
|
rpm-build |
0a0c83 |
"owner/group: %s\n"),
|
|
rpm-build |
0a0c83 |
progname, xquote(path_p, "\n\r"),
|
|
rpm-build |
0a0c83 |
strerror(errno));
|
|
rpm-build |
0a0c83 |
status = 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* chown() clears setuid/setgid so force a chmod if
|
|
rpm-build |
0a0c83 |
* S_ISUID/S_ISGID was expected */
|
|
rpm-build |
0a0c83 |
if ((st.st_mode & flags) & (S_ISUID | S_ISGID))
|
|
rpm-build |
0a0c83 |
chmod_required = 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
mask = S_ISUID | S_ISGID | S_ISVTX;
|
|
rpm-build |
0a0c83 |
if (chmod_required || ((st.st_mode & mask) != (flags & mask))) {
|
|
rpm-build |
0a0c83 |
if (!args.mode)
|
|
rpm-build |
0a0c83 |
args.mode = st.st_mode;
|
|
rpm-build |
0a0c83 |
args.mode &= (S_IRWXU | S_IRWXG | S_IRWXO);
|
|
rpm-build |
0a0c83 |
if (chmod(path_p, flags | args.mode) != 0) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("%s: %s: Cannot change "
|
|
rpm-build |
0a0c83 |
"mode: %s\n"),
|
|
rpm-build |
0a0c83 |
progname, xquote(path_p, "\n\r"),
|
|
rpm-build |
0a0c83 |
strerror(errno));
|
|
rpm-build |
0a0c83 |
status = 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
resume:
|
|
rpm-build |
0a0c83 |
if (path_p) {
|
|
rpm-build |
0a0c83 |
free(path_p);
|
|
rpm-build |
0a0c83 |
path_p = NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (args.seq) {
|
|
rpm-build |
0a0c83 |
seq_free(args.seq);
|
|
rpm-build |
0a0c83 |
args.seq = NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
getout:
|
|
rpm-build |
0a0c83 |
if (path_p) {
|
|
rpm-build |
0a0c83 |
free(path_p);
|
|
rpm-build |
0a0c83 |
path_p = NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (args.seq) {
|
|
rpm-build |
0a0c83 |
seq_free(args.seq);
|
|
rpm-build |
0a0c83 |
args.seq = NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return status;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
fail_errno:
|
|
rpm-build |
0a0c83 |
error = errno;
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
fprintf(stderr, "%s: %s: %s\n", progname, xquote(filename, "\n\r"),
|
|
rpm-build |
0a0c83 |
strerror(error));
|
|
rpm-build |
0a0c83 |
status = 1;
|
|
rpm-build |
0a0c83 |
goto getout;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
void help(void)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
printf(_("%s %s -- set file access control lists\n"),
|
|
rpm-build |
0a0c83 |
progname, VERSION);
|
|
rpm-build |
0a0c83 |
printf(_("Usage: %s %s\n"),
|
|
rpm-build |
0a0c83 |
progname, cmd_line_spec);
|
|
rpm-build |
0a0c83 |
printf(_(
|
|
rpm-build |
0a0c83 |
" -m, --modify=acl modify the current ACL(s) of file(s)\n"
|
|
rpm-build |
0a0c83 |
" -M, --modify-file=file read ACL entries to modify from file\n"
|
|
rpm-build |
0a0c83 |
" -x, --remove=acl remove entries from the ACL(s) of file(s)\n"
|
|
rpm-build |
0a0c83 |
" -X, --remove-file=file read ACL entries to remove from file\n"
|
|
rpm-build |
0a0c83 |
" -b, --remove-all remove all extended ACL entries\n"
|
|
rpm-build |
0a0c83 |
" -k, --remove-default remove the default ACL\n"));
|
|
rpm-build |
0a0c83 |
#if !POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
if (!posixly_correct) {
|
|
rpm-build |
0a0c83 |
printf(_(
|
|
rpm-build |
0a0c83 |
" --set=acl set the ACL of file(s), replacing the current ACL\n"
|
|
rpm-build |
0a0c83 |
" --set-file=file read ACL entries to set from file\n"
|
|
rpm-build |
0a0c83 |
" --mask do recalculate the effective rights mask\n"));
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
printf(_(
|
|
rpm-build |
0a0c83 |
" -n, --no-mask don't recalculate the effective rights mask\n"
|
|
rpm-build |
0a0c83 |
" -d, --default operations apply to the default ACL\n"));
|
|
rpm-build |
0a0c83 |
#if !POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
if (!posixly_correct) {
|
|
rpm-build |
0a0c83 |
printf(_(
|
|
rpm-build |
0a0c83 |
" -R, --recursive recurse into subdirectories\n"
|
|
rpm-build |
0a0c83 |
" -L, --logical logical walk, follow symbolic links\n"
|
|
rpm-build |
0a0c83 |
" -P, --physical physical walk, do not follow symbolic links\n"
|
|
rpm-build |
0a0c83 |
" --restore=file restore ACLs (inverse of `getfacl -R')\n"
|
|
rpm-build |
0a0c83 |
" --test test mode (ACLs are not modified)\n"));
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
printf(_(
|
|
rpm-build |
0a0c83 |
" -v, --version print version and exit\n"
|
|
rpm-build |
0a0c83 |
" -h, --help this help text\n"));
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
int next_file(const char *arg, seq_t seq)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
char *line;
|
|
rpm-build |
0a0c83 |
int errors = 0;
|
|
rpm-build |
0a0c83 |
struct do_set_args args;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
args.seq = seq;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (strcmp(arg, "-") == 0) {
|
|
rpm-build |
0a0c83 |
while ((line = __acl_next_line(stdin)))
|
|
rpm-build |
0a0c83 |
errors = walk_tree(line, walk_flags, 0, do_set, &args);
|
|
rpm-build |
0a0c83 |
if (!feof(stdin)) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("%s: Standard input: %s\n"),
|
|
rpm-build |
0a0c83 |
progname, strerror(errno));
|
|
rpm-build |
0a0c83 |
errors = 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
errors = walk_tree(arg, walk_flags, 0, do_set, &args);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return errors ? 1 : 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define ERRNO_ERROR(s) \
|
|
rpm-build |
0a0c83 |
({status = (s); goto errno_error; })
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
int main(int argc, char *argv[])
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
int opt;
|
|
rpm-build |
0a0c83 |
int saw_files = 0;
|
|
rpm-build |
0a0c83 |
int status = 0;
|
|
rpm-build |
0a0c83 |
FILE *file;
|
|
rpm-build |
0a0c83 |
int which;
|
|
rpm-build |
0a0c83 |
int lineno;
|
|
rpm-build |
0a0c83 |
int error;
|
|
rpm-build |
0a0c83 |
seq_t seq;
|
|
rpm-build |
0a0c83 |
int seq_cmd, parse_mode;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
progname = basename(argv[0]);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
cmd_line_options = POSIXLY_CMD_LINE_OPTIONS;
|
|
rpm-build |
0a0c83 |
cmd_line_spec = _(POSIXLY_CMD_LINE_SPEC);
|
|
rpm-build |
0a0c83 |
#else
|
|
rpm-build |
0a0c83 |
if (getenv(POSIXLY_CORRECT_STR))
|
|
rpm-build |
0a0c83 |
posixly_correct = 1;
|
|
rpm-build |
0a0c83 |
if (!posixly_correct) {
|
|
rpm-build |
0a0c83 |
cmd_line_options = CMD_LINE_OPTIONS;
|
|
rpm-build |
0a0c83 |
cmd_line_spec = _(CMD_LINE_SPEC);
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
cmd_line_options = POSIXLY_CMD_LINE_OPTIONS;
|
|
rpm-build |
0a0c83 |
cmd_line_spec = _(POSIXLY_CMD_LINE_SPEC);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
setlocale(LC_CTYPE, "");
|
|
rpm-build |
0a0c83 |
setlocale(LC_MESSAGES, "");
|
|
rpm-build |
0a0c83 |
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
rpm-build |
0a0c83 |
textdomain(PACKAGE);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
seq = seq_init();
|
|
rpm-build |
0a0c83 |
if (!seq)
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
while ((opt = getopt_long(argc, argv, cmd_line_options,
|
|
rpm-build |
0a0c83 |
long_options, NULL)) != -1) {
|
|
rpm-build |
0a0c83 |
/* we remember the two REMOVE_ACL commands of the set
|
|
rpm-build |
0a0c83 |
operations because we may later need to delete them. */
|
|
rpm-build |
0a0c83 |
cmd_t seq_remove_default_acl_cmd = NULL;
|
|
rpm-build |
0a0c83 |
cmd_t seq_remove_acl_cmd = NULL;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (opt != '\1' && saw_files) {
|
|
rpm-build |
0a0c83 |
seq_free(seq);
|
|
rpm-build |
0a0c83 |
seq = seq_init();
|
|
rpm-build |
0a0c83 |
if (!seq)
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
saw_files = 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
switch (opt) {
|
|
rpm-build |
0a0c83 |
case 'b': /* remove all extended entries */
|
|
rpm-build |
0a0c83 |
if (seq_append_cmd(seq, CMD_REMOVE_EXTENDED_ACL,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_ACCESS) ||
|
|
rpm-build |
0a0c83 |
seq_append_cmd(seq, CMD_REMOVE_ACL,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_DEFAULT))
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'k': /* remove default ACL */
|
|
rpm-build |
0a0c83 |
if (seq_append_cmd(seq, CMD_REMOVE_ACL,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_DEFAULT))
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'n': /* do not recalculate mask */
|
|
rpm-build |
0a0c83 |
opt_recalculate = -1;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'r': /* force recalculate mask */
|
|
rpm-build |
0a0c83 |
opt_recalculate = 1;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'd': /* operations apply to default ACL */
|
|
rpm-build |
0a0c83 |
opt_promote = 1;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 's': /* set */
|
|
rpm-build |
0a0c83 |
if (seq_append_cmd(seq, CMD_REMOVE_ACL,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_ACCESS))
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
seq_remove_acl_cmd = seq->s_last;
|
|
rpm-build |
0a0c83 |
if (seq_append_cmd(seq, CMD_REMOVE_ACL,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_DEFAULT))
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
seq_remove_default_acl_cmd = seq->s_last;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
seq_cmd = CMD_ENTRY_REPLACE;
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_WITH_PERM;
|
|
rpm-build |
0a0c83 |
goto set_modify_delete;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'm': /* modify */
|
|
rpm-build |
0a0c83 |
seq_cmd = CMD_ENTRY_REPLACE;
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_WITH_PERM;
|
|
rpm-build |
0a0c83 |
goto set_modify_delete;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'x': /* delete */
|
|
rpm-build |
0a0c83 |
seq_cmd = CMD_REMOVE_ENTRY;
|
|
rpm-build |
0a0c83 |
#if POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_ANY_PERM;
|
|
rpm-build |
0a0c83 |
#else
|
|
rpm-build |
0a0c83 |
if (posixly_correct)
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_ANY_PERM;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_NO_PERM;
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
goto set_modify_delete;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
set_modify_delete:
|
|
rpm-build |
0a0c83 |
if (!posixly_correct)
|
|
rpm-build |
0a0c83 |
parse_mode |= SEQ_PARSE_DEFAULT;
|
|
rpm-build |
0a0c83 |
if (opt_promote)
|
|
rpm-build |
0a0c83 |
parse_mode |= SEQ_PROMOTE_ACL;
|
|
rpm-build |
0a0c83 |
if (parse_acl_seq(seq, optarg, &which,
|
|
rpm-build |
0a0c83 |
seq_cmd, parse_mode) != 0) {
|
|
rpm-build |
0a0c83 |
if (which < 0 ||
|
|
rpm-build |
0a0c83 |
(size_t) which >= strlen(optarg)) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _(
|
|
rpm-build |
0a0c83 |
"%s: Option "
|
|
rpm-build |
0a0c83 |
"-%c incomplete\n"),
|
|
rpm-build |
0a0c83 |
progname, opt);
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _(
|
|
rpm-build |
0a0c83 |
"%s: Option "
|
|
rpm-build |
0a0c83 |
"-%c: %s near "
|
|
rpm-build |
0a0c83 |
"character %d\n"),
|
|
rpm-build |
0a0c83 |
progname, opt,
|
|
rpm-build |
0a0c83 |
strerror(errno),
|
|
rpm-build |
0a0c83 |
which+1);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
status = 2;
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'S': /* set from file */
|
|
rpm-build |
0a0c83 |
if (seq_append_cmd(seq, CMD_REMOVE_ACL,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_ACCESS))
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
seq_remove_acl_cmd = seq->s_last;
|
|
rpm-build |
0a0c83 |
if (seq_append_cmd(seq, CMD_REMOVE_ACL,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_DEFAULT))
|
|
rpm-build |
0a0c83 |
ERRNO_ERROR(1);
|
|
rpm-build |
0a0c83 |
seq_remove_default_acl_cmd = seq->s_last;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
seq_cmd = CMD_ENTRY_REPLACE;
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_WITH_PERM;
|
|
rpm-build |
0a0c83 |
goto set_modify_delete_from_file;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'M': /* modify from file */
|
|
rpm-build |
0a0c83 |
seq_cmd = CMD_ENTRY_REPLACE;
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_WITH_PERM;
|
|
rpm-build |
0a0c83 |
goto set_modify_delete_from_file;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'X': /* delete from file */
|
|
rpm-build |
0a0c83 |
seq_cmd = CMD_REMOVE_ENTRY;
|
|
rpm-build |
0a0c83 |
#if POSIXLY_CORRECT
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_ANY_PERM;
|
|
rpm-build |
0a0c83 |
#else
|
|
rpm-build |
0a0c83 |
if (posixly_correct)
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_ANY_PERM;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
parse_mode = SEQ_PARSE_NO_PERM;
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
goto set_modify_delete_from_file;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
set_modify_delete_from_file:
|
|
rpm-build |
0a0c83 |
if (!posixly_correct)
|
|
rpm-build |
0a0c83 |
parse_mode |= SEQ_PARSE_DEFAULT;
|
|
rpm-build |
0a0c83 |
if (opt_promote)
|
|
rpm-build |
0a0c83 |
parse_mode |= SEQ_PROMOTE_ACL;
|
|
rpm-build |
0a0c83 |
if (strcmp(optarg, "-") == 0) {
|
|
rpm-build |
0a0c83 |
file = stdin;
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
file = fopen(optarg, "r");
|
|
rpm-build |
0a0c83 |
if (file == NULL) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, "%s: %s: %s\n",
|
|
rpm-build |
0a0c83 |
progname,
|
|
rpm-build |
0a0c83 |
xquote(optarg, "\n\r"),
|
|
rpm-build |
0a0c83 |
strerror(errno));
|
|
rpm-build |
0a0c83 |
status = 2;
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
lineno = 0;
|
|
rpm-build |
0a0c83 |
error = read_acl_seq(file, seq, seq_cmd,
|
|
rpm-build |
0a0c83 |
parse_mode, &lineno, NULL);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (file != stdin) {
|
|
rpm-build |
0a0c83 |
fclose(file);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (error) {
|
|
rpm-build |
0a0c83 |
if (!errno)
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (file != stdin) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _(
|
|
rpm-build |
0a0c83 |
"%s: %s in line "
|
|
rpm-build |
0a0c83 |
"%d of file %s\n"),
|
|
rpm-build |
0a0c83 |
progname,
|
|
rpm-build |
0a0c83 |
strerror(errno),
|
|
rpm-build |
0a0c83 |
lineno,
|
|
rpm-build |
0a0c83 |
xquote(optarg, "\n\r"));
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _(
|
|
rpm-build |
0a0c83 |
"%s: %s in line "
|
|
rpm-build |
0a0c83 |
"%d of standard "
|
|
rpm-build |
0a0c83 |
"input\n"), progname,
|
|
rpm-build |
0a0c83 |
strerror(errno),
|
|
rpm-build |
0a0c83 |
lineno);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
status = 2;
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case '\1': /* file argument */
|
|
rpm-build |
0a0c83 |
if (seq_empty(seq))
|
|
rpm-build |
0a0c83 |
goto synopsis;
|
|
rpm-build |
0a0c83 |
saw_files = 1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
status = next_file(optarg, seq);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'B': /* restore ACL backup */
|
|
rpm-build |
0a0c83 |
saw_files = 1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (strcmp(optarg, "-") == 0)
|
|
rpm-build |
0a0c83 |
file = stdin;
|
|
rpm-build |
0a0c83 |
else {
|
|
rpm-build |
0a0c83 |
file = fopen(optarg, "r");
|
|
rpm-build |
0a0c83 |
if (file == NULL) {
|
|
rpm-build |
0a0c83 |
fprintf(stderr, "%s: %s: %s\n",
|
|
rpm-build |
0a0c83 |
progname,
|
|
rpm-build |
0a0c83 |
xquote(optarg, "\n\r"),
|
|
rpm-build |
0a0c83 |
strerror(errno));
|
|
rpm-build |
0a0c83 |
status = 2;
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
status = restore(file,
|
|
rpm-build |
0a0c83 |
(file == stdin) ? NULL : optarg);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (file != stdin)
|
|
rpm-build |
0a0c83 |
fclose(file);
|
|
rpm-build |
0a0c83 |
if (status != 0)
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'R': /* recursive */
|
|
rpm-build |
0a0c83 |
walk_flags |= WALK_TREE_RECURSIVE;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'L': /* follow symlinks */
|
|
rpm-build |
0a0c83 |
walk_flags |= WALK_TREE_LOGICAL | WALK_TREE_DEREFERENCE;
|
|
rpm-build |
0a0c83 |
walk_flags &= ~WALK_TREE_PHYSICAL;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'P': /* do not follow symlinks */
|
|
rpm-build |
0a0c83 |
walk_flags |= WALK_TREE_PHYSICAL;
|
|
rpm-build |
0a0c83 |
walk_flags &= ~(WALK_TREE_LOGICAL | WALK_TREE_DEREFERENCE |
|
|
rpm-build |
0a0c83 |
WALK_TREE_DEREFERENCE_TOPLEVEL);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 't': /* test mode */
|
|
rpm-build |
0a0c83 |
opt_test = 1;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'v': /* print version and exit */
|
|
rpm-build |
0a0c83 |
printf("%s " VERSION "\n", progname);
|
|
rpm-build |
0a0c83 |
status = 0;
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'h': /* help! */
|
|
rpm-build |
0a0c83 |
help();
|
|
rpm-build |
0a0c83 |
status = 0;
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case ':': /* option missing */
|
|
rpm-build |
0a0c83 |
case '?': /* unknown option */
|
|
rpm-build |
0a0c83 |
default:
|
|
rpm-build |
0a0c83 |
goto synopsis;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (seq_remove_acl_cmd) {
|
|
rpm-build |
0a0c83 |
/* This was a set operation. Check if there are
|
|
rpm-build |
0a0c83 |
actually entries of ACL_TYPE_ACCESS; if there
|
|
rpm-build |
0a0c83 |
are none, we need to remove this command! */
|
|
rpm-build |
0a0c83 |
if (!has_any_of_type(seq_remove_acl_cmd->c_next,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_ACCESS))
|
|
rpm-build |
0a0c83 |
seq_delete_cmd(seq, seq_remove_acl_cmd);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (seq_remove_default_acl_cmd) {
|
|
rpm-build |
0a0c83 |
/* This was a set operation. Check if there are
|
|
rpm-build |
0a0c83 |
actually entries of ACL_TYPE_DEFAULT; if there
|
|
rpm-build |
0a0c83 |
are none, we need to remove this command! */
|
|
rpm-build |
0a0c83 |
if (!has_any_of_type(seq_remove_default_acl_cmd->c_next,
|
|
rpm-build |
0a0c83 |
ACL_TYPE_DEFAULT))
|
|
rpm-build |
0a0c83 |
seq_delete_cmd(seq, seq_remove_default_acl_cmd);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
while (optind < argc) {
|
|
rpm-build |
0a0c83 |
if(!seq)
|
|
rpm-build |
0a0c83 |
goto synopsis;
|
|
rpm-build |
0a0c83 |
if (seq_empty(seq))
|
|
rpm-build |
0a0c83 |
goto synopsis;
|
|
rpm-build |
0a0c83 |
saw_files = 1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
status = next_file(argv[optind++], seq);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (!saw_files)
|
|
rpm-build |
0a0c83 |
goto synopsis;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
synopsis:
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("Usage: %s %s\n"),
|
|
rpm-build |
0a0c83 |
progname, cmd_line_spec);
|
|
rpm-build |
0a0c83 |
fprintf(stderr, _("Try `%s --help' for more information.\n"),
|
|
rpm-build |
0a0c83 |
progname);
|
|
rpm-build |
0a0c83 |
status = 2;
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
errno_error:
|
|
rpm-build |
0a0c83 |
fprintf(stderr, "%s: %s\n", progname, strerror(errno));
|
|
rpm-build |
0a0c83 |
goto cleanup;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
cleanup:
|
|
rpm-build |
0a0c83 |
if (seq)
|
|
rpm-build |
0a0c83 |
seq_free(seq);
|
|
rpm-build |
0a0c83 |
return status;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|