Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport Opendistro 1.8 #994

Merged
merged 4 commits into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.bulk.BulkItemRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkShardRequest;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.get.MultiGetAction;
Expand All @@ -68,6 +69,7 @@
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
Expand Down Expand Up @@ -185,6 +187,22 @@ public PrivilegesEvaluatorResponse evaluate(final User user, String action0, fin
log.debug("action: "+action0+" ("+request.getClass().getSimpleName()+")");
}

if (request instanceof BulkRequest && (Strings.isNullOrEmpty(user.getRequestedTenant()))) {
sujithvm marked this conversation as resolved.
Show resolved Hide resolved
// Shortcut for bulk actions. The details are checked on the lower level of the BulkShardRequests (Action indices:data/write/bulk[s]).
// This shortcut is only possible if the default tenant is selected, as we might need to rewrite the request for non-default tenants.
// No further access check for the default tenant is necessary, as access will be also checked on the TransportShardBulkAction level.

if (!securityRoles.impliesClusterPermissionPermission(action0)) {
presponse.missingPrivileges.add(action0);
presponse.allowed = false;
log.info("No cluster-level perm match for {} [Action [{}]] [RolesChecked {}]. No permissions for {}", user, action0,
securityRoles.getRoleNames(), presponse.missingPrivileges);
} else {
presponse.allowed = true;
}
return presponse;
}

final Resolved requestedResolved = irr.resolveRequest(request);

if (log.isDebugEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ private Resolved resolveIndexPatterns(final IndicesOptions indicesOptions, final
remoteIndices = Collections.emptySet();
}

final Set<String> matchingAliases;
Set<String> matchingAllIndices;
final Collection<String> matchingAliases;
Collection<String> matchingAllIndices;

if (isLocalAll(requestedPatterns0)) {
if (log.isTraceEnabled()) {
Expand Down Expand Up @@ -237,9 +237,7 @@ private Resolved resolveIndexPatterns(final IndicesOptions indicesOptions, final
.collect(Collectors.toSet());

try {
matchingAllIndices = new HashSet<>(Arrays.asList(
resolver.concreteIndexNames(state, indicesOptions, localRequestedPatterns.toArray(new String[0]))
));
matchingAllIndices = Arrays.asList(resolver.concreteIndexNames(state, indicesOptions, localRequestedPatterns.toArray(new String[0])));
if (log.isDebugEnabled()) {
log.debug("Resolved pattern {} to {}", localRequestedPatterns, matchingAllIndices);
}
Expand All @@ -252,7 +250,7 @@ private Resolved resolveIndexPatterns(final IndicesOptions indicesOptions, final
}
}

return new Resolved(matchingAliases, matchingAllIndices, new HashSet<>(Arrays.asList(requestedPatterns0)), remoteIndices);
return new Resolved(matchingAliases, matchingAllIndices, Arrays.asList(requestedPatterns0), remoteIndices);

}

Expand Down Expand Up @@ -348,53 +346,61 @@ public Resolved resolveRequest(final Object request) {

public final static class Resolved implements Serializable, Writeable {

/**
*
*/
private static final Set<String> All_SET = Collections.singleton("*");
private static final Set<String> All_SET = ImmutableSet.of("*");
private static final Set<String> types = All_SET;
private static final long serialVersionUID = 1L;
public final static Resolved _LOCAL_ALL = new Resolved(All_SET, All_SET, All_SET, Collections.emptySet());
public static final Resolved _LOCAL_ALL = new Resolved(All_SET, All_SET, All_SET, Collections.emptySet());

private final Set<String> aliases;
private final Set<String> allIndices;
private static final Set<String> types = ImmutableSet.of("*");

private final Set<String> originalRequested;
private final Set<String> remoteIndices;
private final boolean isLocalAll;

private Resolved(final Set<String> aliases, final Set<String> allIndices,
final Set<String> originalRequested, final Set<String> remoteIndices) {
this.aliases = aliases;
this.allIndices = allIndices;
this.originalRequested = originalRequested;
this.remoteIndices = remoteIndices;
private Resolved(final Collection<String> aliases,
final Collection<String> allIndices,
final Collection<String> originalRequested,
final Collection<String> remoteIndices) {
this.aliases = ImmutableSet.copyOf(aliases);
this.allIndices = ImmutableSet.copyOf(allIndices);
this.originalRequested = ImmutableSet.copyOf(originalRequested);
this.remoteIndices = ImmutableSet.copyOf(remoteIndices);
this.isLocalAll = IndexResolverReplacer.isLocalAll(originalRequested.toArray(new String[0])) || (aliases.contains("*") && allIndices.contains("*"));
}

public boolean isLocalAll() {
if(IndexResolverReplacer.isLocalAll(originalRequested==null?null:originalRequested.toArray(new String[0]))) {
return true;
}
public Resolved(final StreamInput in) throws IOException {
this(in.readList(StreamInput::readString),
in.readList(StreamInput::readString),
in.readList(StreamInput::readString),
in.readList(StreamInput::readString));
}

return aliases.contains("*") && allIndices.contains("*") && types.contains("*");
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeStringCollection(aliases);
out.writeStringCollection(allIndices);
out.writeStringCollection(originalRequested);
out.writeStringCollection(remoteIndices);
}

public boolean isLocalAll() {
return isLocalAll;
}

public Set<String> getAliases() {
return Collections.unmodifiableSet(aliases);
return aliases;
}

public Set<String> getAllIndices() {
return Collections.unmodifiableSet(allIndices);
return allIndices;
}

public Set<String> getTypes() {
return types;
}

public Set<String> getOriginalRequested() {
return Collections.unmodifiableSet(originalRequested);
}

public Set<String> getRemoteIndices() {
return Collections.unmodifiableSet(remoteIndices);
return remoteIndices;
}

@Override
Expand Down Expand Up @@ -446,37 +452,17 @@ public boolean equals(Object obj) {
return true;
}


private static class Builder {
private final Set<String> aliases;
private final Set<String> allIndices;
private final Set<String> originalRequested;
private final Set<String> remoteIndices;

private final Set<String> aliases = new HashSet<String>();
private final Set<String> allIndices = new HashSet<String>();
private final Set<String> originalRequested = new HashSet<String>();
private final Set<String> remoteIndices = new HashSet<String>();

public Builder() {
this(null, null, null, null);
}

public Builder(Collection<String> aliases, Collection<String> allIndices,
String[] originalRequested, Collection<String> remoteIndices) {

if(aliases != null) {
this.aliases.addAll(aliases);
}


if(allIndices != null) {
this.allIndices.addAll(allIndices);
}

if(originalRequested != null) {
this.originalRequested.addAll(Arrays.asList(originalRequested));
}

if(remoteIndices != null) {
this.remoteIndices.addAll(remoteIndices);
}
Builder() {
this.aliases = new HashSet<>();
this.allIndices = new HashSet<>();
this.originalRequested = new HashSet<>();
this.remoteIndices = new HashSet<>();
}

public Builder add(Resolved r) {
Expand All @@ -486,41 +472,11 @@ public Builder add(Resolved r) {
this.remoteIndices.addAll(r.remoteIndices);
return this;
}

public Builder addOriginalRequested(List<String> originalRequested) {
if(originalRequested != null) {
this.originalRequested.addAll(originalRequested);
}
return this;
}

public Builder addRemoteIndices(Set<String> remoteIndices) {
if(remoteIndices != null) {
this.remoteIndices.addAll(remoteIndices);
}
return this;
}

public Resolved build() {
return new Resolved(aliases, allIndices, originalRequested, remoteIndices);
}
}

public Resolved(final StreamInput in) throws IOException {
aliases = new HashSet<String>(in.readList(StreamInput::readString));
allIndices = new HashSet<String>(in.readList(StreamInput::readString));
originalRequested = new HashSet<String>(in.readList(StreamInput::readString));
remoteIndices = new HashSet<String>(in.readList(StreamInput::readString));
}


@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeStringCollection(new ArrayList<>(aliases));
out.writeStringCollection(new ArrayList<>(allIndices));
out.writeStringCollection(new ArrayList<>(originalRequested));
out.writeStringCollection(new ArrayList<>(remoteIndices));
}
}

private List<String> renamedIndices(final RestoreSnapshotRequest request, final List<String> filteredIndices) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1096,47 +1096,52 @@ public Map<String, Boolean> mapTenants(final User user, Set<String> roles) {
private class RoleMappingHolder {

private ListMultimap<String, String> users;
private ListMultimap<Set<String>, String> abars;
private ListMultimap<List<WildcardMatcher>, String> abars;
private ListMultimap<String, String> bars;
private ListMultimap<String, String> hosts;
private final String hostResolverMode;

private List<WildcardMatcher> userMatchers;
private List<WildcardMatcher> barMatchers;
private List<WildcardMatcher> hostMatchers;

private RoleMappingHolder(final SecurityDynamicConfiguration<RoleMappingsV6> rolesMapping, final String hostResolverMode) {

this.hostResolverMode = hostResolverMode;

if (rolesMapping != null) {

final ListMultimap<String, String> users_ = ArrayListMultimap.create();
final ListMultimap<Set<String>, String> abars_ = ArrayListMultimap.create();
final ListMultimap<String, String> bars_ = ArrayListMultimap.create();
final ListMultimap<String, String> hosts_ = ArrayListMultimap.create();
users = ArrayListMultimap.create();
abars = ArrayListMultimap.create();
bars = ArrayListMultimap.create();
hosts = ArrayListMultimap.create();

for (final Entry<String, RoleMappingsV6> roleMap : rolesMapping.getCEntries().entrySet()) {
final String roleMapKey = roleMap.getKey();
final RoleMappingsV6 roleMapValue = roleMap.getValue();

for (String u : roleMap.getValue().getUsers()) {
users_.put(u, roleMap.getKey());
for (String u : roleMapValue.getUsers()) {
users.put(u, roleMapKey);
}

final Set<String> abar = new HashSet<String>(roleMap.getValue().getAndBackendroles());
final Set<String> abar = new HashSet<>(roleMapValue.getAndBackendroles());

if (!abar.isEmpty()) {
abars_.put(abar, roleMap.getKey());
abars.put(WildcardMatcher.matchers(abar), roleMapKey);
}

for (String bar : roleMap.getValue().getBackendroles()) {
bars_.put(bar, roleMap.getKey());
for (String bar : roleMapValue.getBackendroles()) {
bars.put(bar, roleMapKey);
}

for (String host : roleMap.getValue().getHosts()) {
hosts_.put(host, roleMap.getKey());
for (String host : roleMapValue.getHosts()) {
hosts.put(host, roleMapKey);
}
}

users = users_;
abars = abars_;
bars = bars_;
hosts = hosts_;
userMatchers = WildcardMatcher.matchers(users.keySet());
barMatchers = WildcardMatcher.matchers(bars.keySet());
hostMatchers = WildcardMatcher.matchers(hosts.keySet());
}
}

Expand All @@ -1146,7 +1151,7 @@ private Set<String> map(final User user, final TransportAddress caller) {
return Collections.emptySet();
}

final Set<String> securityRoles = new TreeSet<String>();
final Set<String> securityRoles = new HashSet<>();

if (rolesMappingResolution == ConfigConstants.RolesMappingResolution.BOTH
|| rolesMappingResolution == ConfigConstants.RolesMappingResolution.BACKENDROLES_ONLY) {
Expand All @@ -1159,16 +1164,16 @@ private Set<String> map(final User user, final TransportAddress caller) {
if (((rolesMappingResolution == ConfigConstants.RolesMappingResolution.BOTH
|| rolesMappingResolution == ConfigConstants.RolesMappingResolution.MAPPING_ONLY))) {

for (String p : WildcardMatcher.getAllMatchingPatterns(WildcardMatcher.matchers(users.keySet()), user.getName())) {
for (String p : WildcardMatcher.getAllMatchingPatterns(userMatchers, user.getName())) {
securityRoles.addAll(users.get(p));
}

for (String p : WildcardMatcher.getAllMatchingPatterns(WildcardMatcher.matchers(bars.keySet()), user.getRoles())) {
for (String p : WildcardMatcher.getAllMatchingPatterns(barMatchers, user.getRoles())) {
securityRoles.addAll(bars.get(p));
}

for (Set<String> patterns : abars.keySet()) {
if (patterns.stream().allMatch(p -> WildcardMatcher.from(p).matchAny(user.getRoles()))) {
for (List<WildcardMatcher> patterns : abars.keySet()) {
if (patterns.stream().allMatch(p -> p.matchAny(user.getRoles()))) {
securityRoles.addAll(abars.get(patterns));
}
}
Expand Down
Loading