static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
static OperationMask arg_operation = 0;
static bool arg_boot = false;
+static bool arg_graceful = false;
static PagerFlags arg_pager_flags = 0;
static char **arg_include_prefixes = NULL;
r = parse_acl(item->argument, &item->acl_access, &item->acl_access_exec,
&item->acl_default, !item->append_or_force);
if (r < 0)
- log_warning_errno(r, "Failed to parse ACL \"%s\", ignoring: %m", item->argument);
+ log_full_errno(arg_graceful && IN_SET(r, -ENOENT, -ESRCH) ? LOG_DEBUG : LOG_WARNING,
+ r, "Failed to parse ACL \"%s\", ignoring: %m", item->argument);
#else
log_warning("ACLs are not supported, ignoring.");
#endif
ItemArray *existing;
OrderedHashmap *h;
int r, pos;
- bool append_or_force = false, boot = false, allow_failure = false, try_replace = false, unbase64 = false, from_cred = false;
+ bool append_or_force = false, boot = false, allow_failure = false, try_replace = false,
+ unbase64 = false, from_cred = false, missing_user_or_group = false;
assert(fname);
assert(line >= 1);
u = user;
r = find_uid(u, &i.uid, uid_cache);
- if (r < 0) {
+ if (r == -ESRCH && arg_graceful) {
+ log_syntax(NULL, LOG_DEBUG, fname, line, r,
+ "%s: user '%s' not found, not adjusting ownership.", i.path, u);
+ missing_user_or_group = true;
+ } else if (r < 0) {
*invalid_config = true;
return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve user '%s': %m", u);
- }
-
- i.uid_set = true;
+ } else
+ i.uid_set = true;
}
if (!empty_or_dash(group)) {
g = group;
r = find_gid(g, &i.gid, gid_cache);
- if (r < 0) {
+ if (r == -ESRCH && arg_graceful) {
+ log_syntax(NULL, LOG_DEBUG, fname, line, r,
+ "%s: group '%s' not found, not adjusting ownership.", i.path, g);
+ missing_user_or_group = true;
+ } else if (r < 0) {
*invalid_config = true;
- return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve group '%s'.", g);
- }
-
- i.gid_set = true;
+ return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve group '%s': %m", g);
+ } else
+ i.gid_set = true;
}
if (!empty_or_dash(mode)) {
CREATE_SUBVOLUME_INHERIT_QUOTA,
CREATE_SUBVOLUME_NEW_QUOTA) ? 0755 : 0644;
+ if (missing_user_or_group && (i.mode & ~0777) != 0) {
+ /* Refuse any special bits for nodes where we couldn't resolve the ownership properly. */
+ mode_t adjusted = i.mode & 0777;
+ log_syntax(NULL, LOG_INFO, fname, line, 0,
+ "Changing mode 0%o to 0%o because of changed ownership.", i.mode, adjusted);
+ i.mode = adjusted;
+ }
+
if (!empty_or_dash(age)) {
const char *a = age;
_cleanup_free_ char *seconds = NULL, *age_by = NULL;
" --clean Clean up marked directories\n"
" --remove Remove marked files/directories\n"
" --boot Execute actions only safe at boot\n"
+ " --graceful Quitely ignore unknown users or groups\n"
" --prefix=PATH Only apply rules with the specified prefix\n"
" --exclude-prefix=PATH Ignore rules with the specified prefix\n"
" -E Ignore rules prefixed with /dev, /proc, /run, /sys\n"
ARG_CLEAN,
ARG_REMOVE,
ARG_BOOT,
+ ARG_GRACEFUL,
ARG_PREFIX,
ARG_EXCLUDE_PREFIX,
ARG_ROOT,
{ "clean", no_argument, NULL, ARG_CLEAN },
{ "remove", no_argument, NULL, ARG_REMOVE },
{ "boot", no_argument, NULL, ARG_BOOT },
+ { "graceful", no_argument, NULL, ARG_GRACEFUL },
{ "prefix", required_argument, NULL, ARG_PREFIX },
{ "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
{ "root", required_argument, NULL, ARG_ROOT },
arg_boot = true;
break;
+ case ARG_GRACEFUL:
+ arg_graceful = true;
+ break;
+
case ARG_PREFIX:
if (strv_push(&arg_include_prefixes, optarg) < 0)
return log_oom();