Skip to content

Commit

Permalink
Introduce dfm_empty_overrides_all setting to enable role without dls/…
Browse files Browse the repository at this point in the history
…fls to override roles with dls/fls

Signed-off-by: cliu123 <[email protected]>
  • Loading branch information
jochenkressin authored and cliu123 committed Apr 8, 2022
1 parent 54a920b commit c70e91e
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ public List<Setting<?>> getSettings() {
settings.add(Setting.boolSetting(ConfigConstants.SECURITY_ALLOW_UNSAFE_DEMOCERTIFICATES, false, Property.NodeScope, Property.Filtered));
settings.add(Setting.boolSetting(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, false, Property.NodeScope, Property.Filtered));
settings.add(Setting.boolSetting(ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST, true, Property.NodeScope, Property.Filtered));
settings.add(Setting.boolSetting(ConfigConstants.SECURITY_DFM_EMPTY_OVERRIDES_ALL, false, Property.NodeScope, Property.Filtered));
settings.add(Setting.groupSetting(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".", Property.NodeScope)); //not filtered here

settings.add(Setting.simpleString(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, Property.NodeScope, Property.Filtered));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ public class PrivilegesEvaluator {
private final ProtectedIndexAccessEvaluator protectedIndexAccessEvaluator;
private final TermsAggregationEvaluator termsAggregationEvaluator;
private final boolean dlsFlsEnabled;
boolean dfmEmptyOverwritesAll;
private DynamicConfigModel dcm;
private final NamedXContentRegistry namedXContentRegistry;

Expand Down Expand Up @@ -164,6 +165,7 @@ public PrivilegesEvaluator(final ClusterService clusterService, final ThreadPool
termsAggregationEvaluator = new TermsAggregationEvaluator();
this.namedXContentRegistry = namedXContentRegistry;
this.dlsFlsEnabled = dlsFlsEnabled;
this.dfmEmptyOverwritesAll = settings.getAsBoolean(ConfigConstants.SECURITY_DFM_EMPTY_OVERRIDES_ALL, false);
}

@Subscribe
Expand Down Expand Up @@ -292,7 +294,7 @@ public PrivilegesEvaluatorResponse evaluate(final User user, String action0, fin
log.trace("dnfof enabled? {}", dnfofEnabled);
}

presponse.evaluatedDlsFlsConfig = getSecurityRoles(mappedRoles).getDlsFls(user, resolver, clusterService, namedXContentRegistry);
presponse.evaluatedDlsFlsConfig = getSecurityRoles(mappedRoles).getDlsFls(user, dfmEmptyOverwritesAll, resolver, clusterService, namedXContentRegistry);


if (isClusterPerm(action0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ public SecurityRoles filter(Set<String> keep) {


@Override
public EvaluatedDlsFlsConfig getDlsFls(User user, IndexNameExpressionResolver resolver, ClusterService cs,
public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, IndexNameExpressionResolver resolver, ClusterService cs,
NamedXContentRegistry namedXContentRegistry) {

final Map<String, Set<String>> dlsQueries = new HashMap<String, Set<String>>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ public SecurityRoles filter(Set<String> keep) {


@Override
public EvaluatedDlsFlsConfig getDlsFls(User user, IndexNameExpressionResolver resolver, ClusterService cs,
public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, IndexNameExpressionResolver resolver, ClusterService cs,
NamedXContentRegistry namedXContentRegistry) {


Expand All @@ -366,19 +366,29 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, IndexNameExpressionResolver re
Map<String, Set<String>> dlsQueriesByIndex = new HashMap<String, Set<String>>();
Map<String, Set<String>> flsFields = new HashMap<String, Set<String>>();
Map<String, Set<String>> maskedFieldsMap = new HashMap<String, Set<String>>();

// we capture all concrete indices that do not have any
// DLS/FLS/Masked Fields restrictions. If the dmf_empty_overwrites_all
// switch is enabled, this trumps any restrictions on those indices
// that may be imposed by other roles.
Set<String> noDlsConcreteIndices = new HashSet<>();
Set<String> noFlsConcreteIndices = new HashSet<>();
Set<String> noMaskedFieldConcreteIndices = new HashSet<>();

for (SecurityRole role : roles) {
for (IndexPattern ip : role.getIpatterns()) {
Set<String> concreteIndices;
concreteIndices = ip.getResolvedIndexPattern(user, resolver, cs);
concreteIndices = ip.getResolvedIndexPattern(user, resolver, cs, false);
String dls = ip.getDlsQuery(user);

if (dls != null && dls.length() > 0) {

for (String concreteIndex : concreteIndices) {
dlsQueriesByIndex.computeIfAbsent(concreteIndex, (key) -> new HashSet<String>()).add(dls);
}
}
} else if (dfmEmptyOverwritesAll) {
noDlsConcreteIndices.addAll(concreteIndices);
}

Set<String> fls = ip.getFls();

Expand All @@ -392,6 +402,8 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, IndexNameExpressionResolver re
flsFields.get(concreteIndex).addAll(Sets.newHashSet(fls));
}
}
} else if (dfmEmptyOverwritesAll) {
noFlsConcreteIndices.addAll(concreteIndices);
}

Set<String> maskedFields = ip.getMaskedFields();
Expand All @@ -406,8 +418,26 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, IndexNameExpressionResolver re
maskedFieldsMap.get(concreteIndex).addAll(Sets.newHashSet(maskedFields));
}
}
}
} else if (dfmEmptyOverwritesAll) {
noMaskedFieldConcreteIndices.addAll(concreteIndices);
}
}
}

if (dfmEmptyOverwritesAll) {
if (log.isDebugEnabled()) {
log.debug("Index patterns with no dls queries attached: {} - They will be removed from {}", noDlsConcreteIndices,
dlsQueriesByIndex.keySet());
log.debug("Index patterns with no fls fields attached: {} - They will be removed from {}", noFlsConcreteIndices,
flsFields.keySet());
log.debug("Index patterns with no masked fields attached: {} - They will be removed from {}", noMaskedFieldConcreteIndices,
maskedFieldsMap.keySet());
}
// removing the indices that do not have D/M/F restrictions
// from the keySet will also modify the underlying map
dlsQueriesByIndex.keySet().removeAll(noDlsConcreteIndices);
flsFields.keySet().removeAll(noFlsConcreteIndices);
maskedFieldsMap.keySet().removeAll(noMaskedFieldConcreteIndices);
}

return new EvaluatedDlsFlsConfig(dlsQueriesByIndex, flsFields, maskedFieldsMap);
Expand Down Expand Up @@ -530,7 +560,7 @@ private Set<String> getAllResolvedPermittedIndices(Resolved resolved, User user,
// }
if (patternMatch) {
//resolved but can contain patterns for nonexistent indices
final WildcardMatcher permitted = WildcardMatcher.from(p.getResolvedIndexPattern(user, resolver, cs)); //maybe they do not exist
final WildcardMatcher permitted = WildcardMatcher.from(p.getResolvedIndexPattern(user, resolver, cs, true)); //maybe they do not exist
final Set<String> res = new HashSet<>();
if (!resolved.isLocalAll() && !resolved.getAllIndices().contains("*") && !resolved.getAllIndices().contains("_all")) {
//resolved but can contain patterns for nonexistent indices
Expand Down Expand Up @@ -722,7 +752,7 @@ public String getUnresolvedIndexPattern(User user) {
return replaceProperties(indexPattern, user);
}

public Set<String> getResolvedIndexPattern(User user, IndexNameExpressionResolver resolver, ClusterService cs) {
public Set<String> getResolvedIndexPattern(User user, IndexNameExpressionResolver resolver, ClusterService cs, boolean appendUnresolved) {
String unresolved = getUnresolvedIndexPattern(user);
WildcardMatcher matcher = WildcardMatcher.from(unresolved);
String[] resolved = null;
Expand All @@ -744,10 +774,12 @@ public Set<String> getResolvedIndexPattern(User user, IndexNameExpressionResolve
if (resolved == null || resolved.length == 0) {
return ImmutableSet.of(unresolved);
} else {
return ImmutableSet.<String>builder()
.addAll(Arrays.asList(resolved))
.add(unresolved)
.build();
ImmutableSet.Builder<String> builder = ImmutableSet.<String>builder()
.addAll(Arrays.asList(resolved));
if (appendUnresolved) {
builder.add(unresolved);
}
return builder.build();
}
}

Expand Down Expand Up @@ -963,12 +995,12 @@ private static boolean impliesTypePerm(Set<IndexPattern> ipatterns, Resolved res
indexMatcherAndPermissions = ipatterns
.stream()
.filter(indexPattern -> "*".equals(indexPattern.getUnresolvedIndexPattern(user)))
.map(p -> new IndexMatcherAndPermissions(p.getResolvedIndexPattern(user, resolver, cs), p.perms))
.map(p -> new IndexMatcherAndPermissions(p.getResolvedIndexPattern(user, resolver, cs, true), p.perms))
.toArray(IndexMatcherAndPermissions[]::new);
} else {
indexMatcherAndPermissions = ipatterns
.stream()
.map(p -> new IndexMatcherAndPermissions(p.getResolvedIndexPattern(user, resolver, cs), p.perms))
.map(p -> new IndexMatcherAndPermissions(p.getResolvedIndexPattern(user, resolver, cs, true), p.perms))
.toArray(IndexMatcherAndPermissions[]::new);
}
return resolvedRequestedIndices
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public interface SecurityRoles {

boolean get(Resolved requestedResolved, User user, String[] allIndexPermsRequiredA, IndexNameExpressionResolver resolver, ClusterService clusterService);

EvaluatedDlsFlsConfig getDlsFls(User user, IndexNameExpressionResolver resolver, ClusterService clusterService, NamedXContentRegistry namedXContentRegistry);
EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, IndexNameExpressionResolver resolver, ClusterService clusterService, NamedXContentRegistry namedXContentRegistry);

Set<String> getAllPermittedIndicesForDashboards(Resolved resolved, User user, String[] actions, IndexNameExpressionResolver resolver, ClusterService cs);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ public class ConfigConstants {
public static final String LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED = "opendistro_security_config.ssl_dual_mode_enabled";
public static final String SECURITY_SSL_CERT_RELOAD_ENABLED = "plugins.security.ssl_cert_reload_enabled";
public static final String SECURITY_DISABLE_ENVVAR_REPLACEMENT = "plugins.security.disable_envvar_replacement";
public static final String SECURITY_DFM_EMPTY_OVERRIDES_ALL = "plugins.security.dfm_empty_overrides_all";

public enum RolesMappingResolution {
MAPPING_ONLY,
Expand Down

0 comments on commit c70e91e

Please sign in to comment.