You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2021/01/15 18:10:23 UTC

[geode] branch support/1.13 updated: GEODE-8782: Add getPrincipal method to FunctionContext interface (#5897)

This is an automated email from the ASF dual-hosted git repository.

jensdeppe pushed a commit to branch support/1.13
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/support/1.13 by this push:
     new b2d2054  GEODE-8782: Add getPrincipal method to FunctionContext interface (#5897)
b2d2054 is described below

commit b2d205459bfe6f045246233fbd3f08fad3e8503b
Author: Jens Deppe <jd...@pivotal.io>
AuthorDate: Fri Jan 15 10:09:28 2021 -0800

    GEODE-8782: Add getPrincipal method to FunctionContext interface (#5897)
    
    - Add the ability to retrieve the Principal from the FunctionContext
      when a SecurityManager is enabled.
    - For rolling upgrade purposes this also includes a new ordinal
      version for GEODE_1_12_1.
    
    - Various test fixes to account for new version
    
    (cherry picked from commit a42f89ab48aaca9aac96a34e80a9b3b2d46bcddd)
    (cherry picked from commit 0ab677199d189527be354fd1427ce29b91ed6b31)
    
    * add 1.13.0 to old versions and set as Benchmarks baseline on develop
    * leave HTTP service off in WAN and Lucene rolling upgrade tests to avoid port conflict
    
    Co-authored-by: Bill Burcham <bi...@gmail.com>
    (cherry picked from commit 9d139b54a2d5229e5415bbed6e01ee95dc5151ec)
    
    * also add 1.13.1 that was missing from old-versions
    * clean up overzealous cherry-pick
    
    Co-authored-by: Dave Barnes <db...@apache.org>
    Co-authored-by: Owen Nichols <on...@apache.org>
---
 .../FunctionExecutionWithPrincipalDUnitTest.java   | 145 +++++++++++++++++++++
 .../codeAnalysis/sanctionedDataSerializables.txt   |   4 +-
 .../geode/cache/execute/FunctionContext.java       |  10 ++
 .../geode/internal/cache/PartitionedRegion.java    |  12 +-
 .../internal/cache/PartitionedRegionDataStore.java |   4 +-
 .../cache/execute/FunctionContextImpl.java         |  17 +++
 .../cache/execute/FunctionRemoteContext.java       |  25 +++-
 .../cache/execute/RegionFunctionContextImpl.java   |  28 +++-
 .../PartitionedRegionFunctionStreamingMessage.java |   2 +-
 .../cache/tier/sockets/CommandInitializer.java     |   2 +
 .../security/IntegratedSecurityService.java        |  14 ++
 .../internal/security/LegacySecurityService.java   |   5 +
 .../geode/internal/security/SecurityService.java   |   2 +
 .../geode/test/junit/rules/ClientCacheRule.java    |   7 +-
 .../internal/security/TestFunctions.java           |  26 +++-
 .../LuceneSearchWithRollingUpgradeTestBase.java    |   3 +
 .../geode/internal/serialization/Version.java      |  18 ++-
 ...ateGatewaySenderMixedSiteOneCurrentSiteTwo.java |   4 +-
 .../cache/wan/WANRollingUpgradeDUnitTest.java      |   3 +
 settings.gradle                                    |   4 +-
 20 files changed, 312 insertions(+), 23 deletions(-)

diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/execute/FunctionExecutionWithPrincipalDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/execute/FunctionExecutionWithPrincipalDUnitTest.java
new file mode 100644
index 0000000..e9d5281
--- /dev/null
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/execute/FunctionExecutionWithPrincipalDUnitTest.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.internal.cache.execute;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.examples.SimpleSecurityManager;
+import org.apache.geode.management.internal.security.TestFunctions.ReadFunction;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.dunit.rules.SerializableFunction;
+import org.apache.geode.test.junit.rules.ClientCacheRule;
+import org.apache.geode.test.junit.rules.ServerStarterRule;
+
+public class FunctionExecutionWithPrincipalDUnitTest {
+
+  private static String PR_REGION_NAME = "partitioned-region";
+  private static String REGION_NAME = "replicated-region";
+  private static Region<String, String> replicateRegion;
+  private static Region<String, String> partitionedRegion;
+
+  private static Function<?> readFunction = new ReadFunction();
+
+  private static MemberVM locator;
+  private static MemberVM server1;
+  private static MemberVM server2;
+  private static ClientCache client;
+
+  @ClassRule
+  public static ClusterStartupRule cluster = new ClusterStartupRule();
+
+  @ClassRule
+  public static ClientCacheRule clientRule = new ClientCacheRule();
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    locator = cluster.startLocatorVM(0, x -> x
+        .withSecurityManager(SimpleSecurityManager.class));
+    int locatorPort = locator.getPort();
+
+    SerializableFunction<ServerStarterRule> startupFunction = x -> x
+        .withConnectionToLocator(locatorPort)
+        .withCredential("cluster", "cluster")
+        .withProperty(ConfigurationProperties.SERIALIZABLE_OBJECT_FILTER,
+            "org.apache.geode.management.internal.security.TestFunctions*");
+
+    server1 = cluster.startServerVM(1, startupFunction);
+    server2 = cluster.startServerVM(2, startupFunction);
+
+    Stream.of(server1, server2).forEach(v -> v.invoke(() -> {
+      ClusterStartupRule.getCache().createRegionFactory(RegionShortcut.REPLICATE).create(
+          REGION_NAME);
+      ClusterStartupRule.getCache().createRegionFactory(RegionShortcut.PARTITION_REDUNDANT)
+          .create(PR_REGION_NAME);
+    }));
+
+    client = clientRule
+        .withLocatorConnection(locatorPort)
+        .withCredential("data", "data")
+        .createCache();
+
+    replicateRegion = clientRule.createProxyRegion(REGION_NAME);
+    partitionedRegion = clientRule.createProxyRegion(PR_REGION_NAME);
+
+    for (int i = 0; i < 10; i++) {
+      replicateRegion.put("key-" + i, "value-" + i);
+      partitionedRegion.put("key-" + i, "value-" + i);
+    }
+  }
+
+  @Test
+  public void verifyPrincipal_whenUsingReplicateRegion_andCallingOnRegion() {
+    FunctionService.onRegion(replicateRegion)
+        .execute(readFunction)
+        .getResult();
+  }
+
+  @Test
+  public void verifyPrincipal_whenUsingPartitionedRegion_andCallingOnRegion() {
+    FunctionService.onRegion(partitionedRegion)
+        .execute(readFunction)
+        .getResult();
+  }
+
+  @Test
+  public void verifyPrincipal_whenUsingPartitionedRegion_andCallingOnRegion_withFilter() {
+    Set<String> filter = new HashSet<>();
+    filter.add("key-1");
+    filter.add("key-2");
+    filter.add("key-4");
+    filter.add("key-7");
+
+    FunctionService.onRegion(partitionedRegion)
+        .withFilter(filter)
+        .execute(readFunction)
+        .getResult();
+  }
+
+  @Test
+  public void verifyPrincipal_whenUsingPartitionedRegion_andCallingOnServer() {
+    FunctionService.onServer(partitionedRegion.getRegionService())
+        .execute(readFunction)
+        .getResult();
+  }
+
+  @Test
+  public void verifyPrincipal_whenUsingPartitionedRegion_andCallingOnServers() {
+    FunctionService.onServers(partitionedRegion.getRegionService())
+        .execute(readFunction)
+        .getResult();
+  }
+
+  @Test
+  public void verifyPrincipal_whenUsingReplicateRegion_andCallingOnServers() {
+    FunctionService.onServers(replicateRegion.getRegionService())
+        .execute(readFunction)
+        .getResult();
+  }
+
+}
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
index 1a65b6c..3a1288a 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
@@ -1293,8 +1293,8 @@ fromData,22
 toData,19
 
 org/apache/geode/internal/cache/execute/FunctionRemoteContext,2
-fromData,124
-toData,102
+fromData,158
+toData,136
 
 org/apache/geode/internal/cache/ha/HARegionQueue$DispatchedAndCurrentEvents,2
 fromData,37
diff --git a/geode-core/src/main/java/org/apache/geode/cache/execute/FunctionContext.java b/geode-core/src/main/java/org/apache/geode/cache/execute/FunctionContext.java
index bc91180..a6a779f 100755
--- a/geode-core/src/main/java/org/apache/geode/cache/execute/FunctionContext.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/execute/FunctionContext.java
@@ -14,10 +14,12 @@
  */
 package org.apache.geode.cache.execute;
 
+
 import org.apache.logging.log4j.util.Strings;
 
 import org.apache.geode.cache.Cache;
 import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.security.LegacySecurityService;
 
 /**
  * Defines the execution context of a {@link Function}. It is required by the
@@ -97,4 +99,12 @@ public interface FunctionContext<T1> {
 
     return member.getId();
   }
+
+  /**
+   * If available, returns the principal that has been authenticated to execute this function. This
+   * will always be null if the {@link LegacySecurityService} is in use.
+   *
+   * @return the principal that has been authenticated
+   */
+  Object getPrincipal();
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
index da3be92..7c4e786 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java
@@ -3713,7 +3713,7 @@ public class PartitionedRegion extends LocalRegion
         FunctionRemoteContext context = new FunctionRemoteContext(function,
             execution.getArgumentsForMember(recip.getId()), memKeys,
             FunctionExecutionNodePruner.getBucketSet(this, memKeys, false, isBucketSetAsFilter),
-            execution.isReExecute(), execution.isFnSerializationReqd());
+            execution.isReExecute(), execution.isFnSerializationReqd(), getPrincipal());
         recipMap.put(recip, context);
       }
       if (logger.isDebugEnabled()) {
@@ -3728,6 +3728,10 @@ public class PartitionedRegion extends LocalRegion
     return localResultCollector;
   }
 
+  private Object getPrincipal() {
+    return cache.getSecurityService().getPrincipal();
+  }
+
   /**
    * Single key execution on single node
    *
@@ -3931,7 +3935,7 @@ public class PartitionedRegion extends LocalRegion
     for (InternalDistributedMember recip : dest) {
       FunctionRemoteContext context = new FunctionRemoteContext(function,
           execution.getArgumentsForMember(recip.getId()), null, memberToBuckets.get(recip),
-          execution.isReExecute(), execution.isFnSerializationReqd());
+          execution.isReExecute(), execution.isFnSerializationReqd(), getPrincipal());
       recipMap.put(recip, context);
     }
     final LocalResultCollector<?, ?> localRC = execution.getLocalResultCollector(function, rc);
@@ -4025,7 +4029,7 @@ public class PartitionedRegion extends LocalRegion
     for (InternalDistributedMember recip : memberToBuckets.keySet()) {
       FunctionRemoteContext context = new FunctionRemoteContext(function,
           execution.getArgumentsForMember(recip.getId()), null, memberToBuckets.get(recip),
-          execution.isReExecute(), execution.isFnSerializationReqd());
+          execution.isReExecute(), execution.isFnSerializationReqd(), getPrincipal());
       recipMap.put(recip, context);
     }
     final LocalResultCollector<?, ?> localResultCollector =
@@ -4957,7 +4961,7 @@ public class PartitionedRegion extends LocalRegion
             resultSender);
 
     FunctionRemoteContext context = new FunctionRemoteContext(function, object, routingKeys,
-        bucketArray, execution.isReExecute(), execution.isFnSerializationReqd());
+        bucketArray, execution.isReExecute(), execution.isFnSerializationReqd(), getPrincipal());
 
     HashMap<InternalDistributedMember, FunctionRemoteContext> recipMap =
         new HashMap<InternalDistributedMember, FunctionRemoteContext>();
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java
index 23a7487..d1d3dba 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java
@@ -2969,7 +2969,7 @@ public class PartitionedRegionDataStore implements HasCachePerfStats {
   public void executeOnDataStore(final Set localKeys, final Function function, final Object object,
       final int prid, final int[] bucketArray, final boolean isReExecute,
       final PartitionedRegionFunctionStreamingMessage msg, long time, ServerConnection servConn,
-      int transactionID) {
+      int transactionID, Object principal) {
 
     if (!areAllBucketsHosted(bucketArray)) {
       throw new BucketMovedException(
@@ -2984,7 +2984,7 @@ public class PartitionedRegionDataStore implements HasCachePerfStats {
         new RegionFunctionContextImpl(getPartitionedRegion().getCache(), function.getId(),
             this.partitionedRegion, object, localKeys, ColocationHelper
                 .constructAndGetAllColocatedLocalDataSet(this.partitionedRegion, bucketArray),
-            bucketArray, resultSender, isReExecute);
+            bucketArray, resultSender, isReExecute, principal);
 
     FunctionStats stats = FunctionStatsManager.getFunctionStats(function.getId(), dm.getSystem());
     long start = stats.startFunctionExecution(function.hasResult());
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionContextImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionContextImpl.java
index c328b2f..c3ef8a7 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionContextImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionContextImpl.java
@@ -21,6 +21,7 @@ import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.RegionFunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.internal.cache.InternalCache;
 
 /**
  * Context available to application functions which is passed from GemFire to {@link Function}. <br>
@@ -45,6 +46,8 @@ public class FunctionContextImpl implements FunctionContext {
 
   private final boolean isPossDup;
 
+  private final Object principal;
+
   public FunctionContextImpl(final Cache cache, final String functionId, final Object args,
       ResultSender resultSender) {
     this(cache, functionId, args, resultSender, false);
@@ -57,6 +60,14 @@ public class FunctionContextImpl implements FunctionContext {
     this.args = args;
     this.resultSender = resultSender;
     this.isPossDup = isPossibleDuplicate;
+
+    Object tmpPrincipal = null;
+    if (cache != null) {
+      if (((InternalCache) cache).getSecurityService() != null) {
+        tmpPrincipal = ((InternalCache) cache).getSecurityService().getPrincipal();
+      }
+    }
+    this.principal = tmpPrincipal;
   }
 
   /**
@@ -89,6 +100,8 @@ public class FunctionContextImpl implements FunctionContext {
     buf.append(this.functionId);
     buf.append(";args=");
     buf.append(this.args);
+    buf.append(";principal=");
+    buf.append(getPrincipal());
     buf.append(']');
     return buf.toString();
   }
@@ -111,4 +124,8 @@ public class FunctionContextImpl implements FunctionContext {
     return cache;
   }
 
+  @Override
+  public Object getPrincipal() {
+    return principal;
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionRemoteContext.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionRemoteContext.java
index e47d492..154b506 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionRemoteContext.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/FunctionRemoteContext.java
@@ -31,8 +31,6 @@ import org.apache.geode.internal.serialization.Version;
 
 /**
  * FunctionContext for remote/target nodes
- *
- *
  */
 public class FunctionRemoteContext implements DataSerializable {
 
@@ -50,16 +48,19 @@ public class FunctionRemoteContext implements DataSerializable {
 
   private Function function;
 
+  private Object principal;
+
   public FunctionRemoteContext() {}
 
   public FunctionRemoteContext(final Function function, Object object, Set filter,
-      int[] bucketArray, boolean isReExecute, boolean isFnSerializationReqd) {
+      int[] bucketArray, boolean isReExecute, boolean isFnSerializationReqd, Object principal) {
     this.function = function;
     this.args = object;
     this.filter = filter;
     this.bucketArray = bucketArray;
     this.isReExecute = isReExecute;
     this.isFnSerializationReqd = isFnSerializationReqd;
+    this.principal = principal;
   }
 
   @Override
@@ -84,6 +85,13 @@ public class FunctionRemoteContext implements DataSerializable {
       this.bucketArray = BucketSetHelper.fromSet(bucketSet);
     }
     this.isReExecute = DataSerializer.readBoolean(in);
+
+    // Account for this change being introduced in ordinals 1.12.1 and 1.13.1 but is not
+    // compatible with 1.13.0.
+    if (StaticSerialization.getVersionForDataStream(in).isNotOlderThan(Version.GEODE_1_12_1)
+        && !StaticSerialization.getVersionForDataStream(in).equals(Version.GEODE_1_13_0)) {
+      this.principal = DataSerializer.readObject(in);
+    }
   }
 
   @Override
@@ -102,6 +110,13 @@ public class FunctionRemoteContext implements DataSerializable {
       DataSerializer.writeHashSet((HashSet) bucketSet, out);
     }
     DataSerializer.writeBoolean(this.isReExecute, out);
+
+    // Account for this change being introduced in ordinals 1.12.1 and 1.13.1 but is not
+    // compatible with 1.13.0.
+    if (StaticSerialization.getVersionForDataStream(out).isNotOlderThan(Version.GEODE_1_12_1)
+        && !StaticSerialization.getVersionForDataStream(out).equals(Version.GEODE_1_13_0)) {
+      DataSerializer.writeObject(this.principal, out);
+    }
   }
 
   public Set getFilter() {
@@ -128,6 +143,10 @@ public class FunctionRemoteContext implements DataSerializable {
     return functionId;
   }
 
+  public Object getPrincipal() {
+    return principal;
+  }
+
   @Override
   public String toString() {
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/RegionFunctionContextImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/RegionFunctionContextImpl.java
index c8d9747..f4e25e0 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/RegionFunctionContextImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/RegionFunctionContextImpl.java
@@ -25,6 +25,7 @@ import org.apache.geode.cache.Region;
 import org.apache.geode.cache.execute.Execution;
 import org.apache.geode.cache.execute.FunctionService;
 import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.LocalDataSet;
 
 /**
@@ -51,16 +52,32 @@ public class RegionFunctionContextImpl extends FunctionContextImpl
 
   private final boolean isPossibleDuplicate;
 
-  public RegionFunctionContextImpl(final Cache cache, final String functionId, final Region dataSet,
-      final Object args, final Set<?> routingObjects,
+  private final Object principal;
+
+  public RegionFunctionContextImpl(final Cache cache, final String functionId,
+      final Region<?, ?> dataSet, final Object args, final Set<?> routingObjects,
       final Map<String, LocalDataSet> colocatedLocalDataMap, int[] localBucketArray,
       ResultSender<?> resultSender, boolean isPossibleDuplicate) {
+    this(cache, functionId, dataSet, args, routingObjects, colocatedLocalDataMap, localBucketArray,
+        resultSender, isPossibleDuplicate, null);
+  }
+
+  public RegionFunctionContextImpl(final Cache cache, final String functionId,
+      final Region<?, ?> dataSet, final Object args, final Set<?> routingObjects,
+      final Map<String, LocalDataSet> colocatedLocalDataMap, int[] localBucketArray,
+      ResultSender<?> resultSender, boolean isPossibleDuplicate, Object principal) {
     super(cache, functionId, args, resultSender);
     this.dataSet = dataSet;
     this.filter = routingObjects;
     this.colocatedLocalDataMap = colocatedLocalDataMap;
     this.localBucketArray = localBucketArray;
     this.isPossibleDuplicate = isPossibleDuplicate;
+
+    if (principal == null) {
+      this.principal = ((InternalCache) cache).getSecurityService().getPrincipal();
+    } else {
+      this.principal = principal;
+    }
     setFunctionContexts();
   }
 
@@ -107,6 +124,8 @@ public class RegionFunctionContextImpl extends FunctionContextImpl
     buf.append(this.filter);
     buf.append(";args=");
     buf.append(getArguments());
+    buf.append(";principal=");
+    buf.append(getPrincipal());
     buf.append(']');
     return buf.toString();
   }
@@ -144,4 +163,9 @@ public class RegionFunctionContextImpl extends FunctionContextImpl
     }
     return this.localBucketArray;
   }
+
+  @Override
+  public Object getPrincipal() {
+    return principal;
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/partitioned/PartitionedRegionFunctionStreamingMessage.java b/geode-core/src/main/java/org/apache/geode/internal/cache/partitioned/PartitionedRegionFunctionStreamingMessage.java
index 23e9d4b2..52b6f98 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/partitioned/PartitionedRegionFunctionStreamingMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/partitioned/PartitionedRegionFunctionStreamingMessage.java
@@ -100,7 +100,7 @@ public class PartitionedRegionFunctionStreamingMessage extends PartitionMessage
       // if null call executeOnDataStore otherwise execute on LocalBuckets
       ds.executeOnDataStore(context.getFilter(), context.getFunction(), context.getArgs(),
           getProcessorId(), context.getBucketArray(), context.isReExecute(), this, startTime, null,
-          0);
+          0, context.getPrincipal());
 
       if (!this.replyLastMsg && context.getFunction().hasResult()) {
         sendReply(getSender(), getProcessorId(), dm,
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CommandInitializer.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CommandInitializer.java
index 7971362..5a66838 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CommandInitializer.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CommandInitializer.java
@@ -338,7 +338,9 @@ public class CommandInitializer {
     allCommands.put(Version.GEODE_1_10_0, geode18Commands);
     allCommands.put(Version.GEODE_1_11_0, geode18Commands);
     allCommands.put(Version.GEODE_1_12_0, geode18Commands);
+    allCommands.put(Version.GEODE_1_12_1, geode18Commands);
     allCommands.put(Version.GEODE_1_13_0, geode18Commands);
+    allCommands.put(Version.GEODE_1_13_1, geode18Commands);
 
     return Collections.unmodifiableMap(allCommands);
   }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java
index 48cc74f..e982c69 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java
@@ -126,6 +126,20 @@ public class IntegratedSecurityService implements SecurityService {
   }
 
   /**
+   * Returns the current principal if one exists or null.
+   *
+   * @return the principal
+   */
+  @Override
+  public Object getPrincipal() {
+    try {
+      return getSubject().getPrincipal();
+    } catch (Exception ex) {
+      return null;
+    }
+  }
+
+  /**
    * @return return a shiro subject
    */
   @Override
diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java
index d097fd9..885c515 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java
@@ -69,6 +69,11 @@ public class LegacySecurityService implements SecurityService {
   }
 
   @Override
+  public Object getPrincipal() {
+    return null;
+  }
+
+  @Override
   public Subject login(Properties credentials) {
     return null;
   }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java
index 3eccdd9..89a415e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java
@@ -33,6 +33,8 @@ public interface SecurityService {
 
   Subject getSubject();
 
+  Object getPrincipal();
+
   Subject login(Properties credentials);
 
   void logout();
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/ClientCacheRule.java b/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/ClientCacheRule.java
index dbcfd8c..5befc5e 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/ClientCacheRule.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/ClientCacheRule.java
@@ -28,6 +28,7 @@ import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionService;
 import org.apache.geode.cache.client.ClientCache;
 import org.apache.geode.cache.client.ClientCacheFactory;
+import org.apache.geode.cache.client.ClientRegionFactory;
 import org.apache.geode.cache.client.ClientRegionShortcut;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.security.templates.UserPasswordAuthInit;
@@ -109,8 +110,10 @@ public class ClientCacheRule extends SerializableExternalResource {
     return cache;
   }
 
-  public Region createProxyRegion(String regionPath) {
-    return cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(regionPath);
+  public <K, V> Region<K, V> createProxyRegion(String regionPath) {
+    ClientRegionFactory<K, V> regionFactory =
+        cache.createClientRegionFactory(ClientRegionShortcut.PROXY);
+    return regionFactory.create(regionPath);
   }
 
   public RegionService createAuthenticatedView(String username, String password) {
diff --git a/geode-junit/src/main/java/org/apache/geode/management/internal/security/TestFunctions.java b/geode-junit/src/main/java/org/apache/geode/management/internal/security/TestFunctions.java
index 8167937..423058c 100644
--- a/geode-junit/src/main/java/org/apache/geode/management/internal/security/TestFunctions.java
+++ b/geode-junit/src/main/java/org/apache/geode/management/internal/security/TestFunctions.java
@@ -17,6 +17,7 @@ package org.apache.geode.management.internal.security;
 
 import static org.apache.geode.security.ResourcePermission.Operation.READ;
 import static org.apache.geode.security.ResourcePermission.Resource.DATA;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
 import java.util.Collection;
@@ -27,11 +28,12 @@ import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.security.ResourcePermission;
 
 public final class TestFunctions implements Serializable {
-  public static class WriteFunction implements Function {
+  public static class WriteFunction implements Function<Object> {
     public static final String SUCCESS_OUTPUT = "writeDataFunctionSucceeded";
 
     @Override
-    public void execute(FunctionContext context) {
+    public void execute(FunctionContext<Object> context) {
+      verifyPrincipal(context);
       context.getResultSender().lastResult(SUCCESS_OUTPUT);
     }
 
@@ -39,13 +41,19 @@ public final class TestFunctions implements Serializable {
     public String getId() {
       return "writeData";
     }
+
+    @Override
+    public boolean optimizeForWrite() {
+      return true;
+    }
   }
 
   public static class ReadFunction implements Function<Object> {
     public static final String SUCCESS_OUTPUT = "readDataFunctionSucceeded";
 
     @Override
-    public void execute(FunctionContext context) {
+    public void execute(FunctionContext<Object> context) {
+      verifyPrincipal(context);
       context.getResultSender().lastResult(SUCCESS_OUTPUT);
     }
 
@@ -58,5 +66,17 @@ public final class TestFunctions implements Serializable {
     public String getId() {
       return "readData";
     }
+
+    @Override
+    public boolean optimizeForWrite() {
+      return true;
+    }
+  }
+
+  private static void verifyPrincipal(FunctionContext<Object> context) {
+    String principal = (String) context.getPrincipal();
+    assertThat(principal).as("Principal cannot be null").isNotNull();
+    assertThat(principal).startsWith("data");
+
   }
 }
diff --git a/geode-lucene/src/upgradeTest/java/org/apache/geode/cache/lucene/LuceneSearchWithRollingUpgradeTestBase.java b/geode-lucene/src/upgradeTest/java/org/apache/geode/cache/lucene/LuceneSearchWithRollingUpgradeTestBase.java
index e07e989..3410215 100644
--- a/geode-lucene/src/upgradeTest/java/org/apache/geode/cache/lucene/LuceneSearchWithRollingUpgradeTestBase.java
+++ b/geode-lucene/src/upgradeTest/java/org/apache/geode/cache/lucene/LuceneSearchWithRollingUpgradeTestBase.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.cache.lucene;
 
+import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
 import static org.apache.geode.test.dunit.Assert.fail;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -112,6 +113,8 @@ public abstract class LuceneSearchWithRollingUpgradeTestBase extends JUnit4Distr
     props.setProperty(DistributionConfig.LOCATORS_NAME, locatorsString);
     props.setProperty(DistributionConfig.LOG_LEVEL_NAME, DUnitLauncher.logLevel);
     props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "true");
+    // Turn off HTTP service, otherwise second (and subsequent) locators will see a port conflict
+    props.setProperty(HTTP_SERVICE_PORT, String.valueOf(0));
     return props;
   }
 
diff --git a/geode-serialization/src/main/java/org/apache/geode/internal/serialization/Version.java b/geode-serialization/src/main/java/org/apache/geode/internal/serialization/Version.java
index d75755b..ea8f462 100644
--- a/geode-serialization/src/main/java/org/apache/geode/internal/serialization/Version.java
+++ b/geode-serialization/src/main/java/org/apache/geode/internal/serialization/Version.java
@@ -52,7 +52,7 @@ public class Version extends VersionOrdinalImpl {
   private final byte release;
   private final byte patch;
 
-  public static final int HIGHEST_VERSION = 120;
+  public static final int HIGHEST_VERSION = 121;
 
   @Immutable
   private static final Version[] VALUES = new Version[HIGHEST_VERSION + 1];
@@ -277,20 +277,34 @@ public class Version extends VersionOrdinalImpl {
   public static final Version GEODE_1_12_0 =
       new Version("GEODE", "1.12.0", (byte) 1, (byte) 12, (byte) 0, (byte) 0, GEODE_1_12_0_ORDINAL);
 
+  private static final short GEODE_1_12_1_ORDINAL = 116;
+
+  @Immutable
+  public static final Version GEODE_1_12_1 =
+      new Version("GEODE", "1.12.1", (byte) 1, (byte) 12, (byte) 1, (byte) 0, GEODE_1_12_1_ORDINAL);
+
   private static final short GEODE_1_13_0_ORDINAL = 120;
 
   @Immutable
   public static final Version GEODE_1_13_0 =
       new Version("GEODE", "1.13.0", (byte) 1, (byte) 13, (byte) 0, (byte) 0, GEODE_1_13_0_ORDINAL);
 
+  private static final short GEODE_1_13_1_ORDINAL = 121;
+
+  @Immutable
+  public static final Version GEODE_1_13_1 =
+      new Version("GEODE", "1.13.1", (byte) 1, (byte) 13, (byte) 1, (byte) 0, GEODE_1_13_1_ORDINAL);
+
   /* NOTE: when adding a new version bump the ordinal by 5. Ordinals can be short ints */
 
+  /* NOTE: when adding a new version bump the ordinal by 2. Ordinals can be short ints */
+
   /**
    * This constant must be set to the most current version of the product. !!! NOTE: update
    * HIGHEST_VERSION when changing CURRENT !!!
    */
   @Immutable
-  public static final Version CURRENT = GEODE_1_13_0;
+  public static final Version CURRENT = GEODE_1_13_1;
 
   /**
    * A lot of versioning code needs access to the current version's ordinal
diff --git a/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeCreateGatewaySenderMixedSiteOneCurrentSiteTwo.java b/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeCreateGatewaySenderMixedSiteOneCurrentSiteTwo.java
index 3bacb81..9933080 100644
--- a/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeCreateGatewaySenderMixedSiteOneCurrentSiteTwo.java
+++ b/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeCreateGatewaySenderMixedSiteOneCurrentSiteTwo.java
@@ -105,7 +105,9 @@ public class WANRollingUpgradeCreateGatewaySenderMixedSiteOneCurrentSiteTwo
     this.gfsh.connectAndVerify(jmxManagerPort, GfshCommandRule.PortType.jmxManager);
     CommandResultAssert cmd = this.gfsh
         .executeAndAssertThat(getCreateGatewaySenderCommand("toSite2", site2DistributedSystemId));
-    if (!majorMinor(oldVersion).equals(majorMinor(Version.CURRENT.getName()))) {
+    // Special case for 1.13.2 since it introduces an ordinal version change
+    if (!majorMinor(oldVersion).equals(majorMinor(Version.CURRENT.getName()))
+        || oldVersion.equals("1.13.0") || oldVersion.equals("1.13.1")) {
       cmd.statusIsError()
           .containsOutput(CliStrings.CREATE_GATEWAYSENDER__MSG__CAN_NOT_CREATE_DIFFERENT_VERSIONS);
     } else {
diff --git a/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeDUnitTest.java b/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeDUnitTest.java
index d3153dd..2d7a9e3 100644
--- a/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeDUnitTest.java
+++ b/geode-wan/src/upgradeTest/java/org/apache/geode/cache/wan/WANRollingUpgradeDUnitTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.cache.wan;
 
 import static org.apache.geode.distributed.ConfigurationProperties.DISTRIBUTED_SYSTEM_ID;
 import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
+import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START;
@@ -134,6 +135,8 @@ public abstract class WANRollingUpgradeDUnitTest extends JUnit4CacheTestCase {
     }
     props.setProperty(LOG_LEVEL, DUnitLauncher.logLevel);
     props.setProperty(ENABLE_CLUSTER_CONFIGURATION, String.valueOf(enableClusterConfiguration));
+    // Turn off HTTP service, otherwise second (and subsequent) locators will see a port conflict
+    props.setProperty(HTTP_SERVICE_PORT, String.valueOf(0));
     return props;
   }
 
diff --git a/settings.gradle b/settings.gradle
index 501a179..e9979a6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -85,7 +85,9 @@ include 'static-analysis:pmd-rules'
  '1.9.2',
  '1.10.0',
  '1.11.0',
- '1.12.0'].each {
+ '1.12.0',
+ '1.13.0',
+ '1.13.1'].each {
   include 'geode-old-versions:'.concat(it)
 }