You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by dl...@apache.org on 2022/12/19 19:12:51 UTC

[accumulo] branch main updated: Added Constant for Zookeeper user Path (#3122)

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

dlmarion pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new 284aee34e8 Added Constant for Zookeeper user Path  (#3122)
284aee34e8 is described below

commit 284aee34e8e6b2c862bae5017dec5a1b2f399a7a
Author: Daniel Roberts <dd...@gmail.com>
AuthorDate: Mon Dec 19 14:12:45 2022 -0500

    Added Constant for Zookeeper user Path  (#3122)
    
    Added constant for "/users" path in ZooKeeper to Constants. Made
    user path for instance available via ServerContext method.
    
    Closes #3120
---
 .../java/org/apache/accumulo/core/Constants.java   |  1 +
 .../org/apache/accumulo/server/ServerContext.java  |  6 ++
 .../server/security/SecurityOperation.java         |  3 +-
 .../security/handler/KerberosAuthenticator.java    |  3 +-
 .../server/security/handler/ZKAuthenticator.java   | 29 ++++----
 .../server/security/handler/ZKAuthorizor.java      | 20 +++---
 .../server/security/handler/ZKPermHandler.java     | 80 +++++++++++-----------
 .../apache/accumulo/server/MockServerContext.java  |  1 +
 .../accumulo/test/conf/util/LegacyPropData.java    | 32 ++++-----
 9 files changed, 90 insertions(+), 85 deletions(-)

diff --git a/core/src/main/java/org/apache/accumulo/core/Constants.java b/core/src/main/java/org/apache/accumulo/core/Constants.java
index 25f8eb2d76..5d37166538 100644
--- a/core/src/main/java/org/apache/accumulo/core/Constants.java
+++ b/core/src/main/java/org/apache/accumulo/core/Constants.java
@@ -35,6 +35,7 @@ public class Constants {
   // Zookeeper locations
   public static final String ZROOT = "/accumulo";
   public static final String ZINSTANCES = "/instances";
+  public static final String ZUSERS = "/users";
 
   public static final String ZTABLES = "/tables";
   public static final byte[] ZTABLES_INITIAL_ID = {'0'};
diff --git a/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java b/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
index e5b339a0d8..03ab556923 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
@@ -92,6 +92,7 @@ public class ServerContext extends ClientContext {
   private final ZooReaderWriter zooReaderWriter;
   private final ServerDirs serverDirs;
   private final Supplier<ZooPropStore> propStore;
+  private final Supplier<String> zkUserPath;
 
   // lazily loaded resources, only loaded when needed
   private final Supplier<TableManager> tableManager;
@@ -113,6 +114,7 @@ public class ServerContext extends ClientContext {
     serverDirs = info.getServerDirs();
 
     propStore = memoize(() -> ZooPropStore.initialize(getInstanceID(), getZooReaderWriter()));
+    zkUserPath = memoize(() -> Constants.ZROOT + "/" + getInstanceID() + Constants.ZUSERS);
 
     tableManager = memoize(() -> new TableManager(this));
     nameAllocator = memoize(() -> new UniqueNameAllocator(this));
@@ -445,4 +447,8 @@ public class ServerContext extends ClientContext {
     return securityOperation.get();
   }
 
+  public String zkUserPath() {
+    return zkUserPath.get();
+  }
+
 }
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
index 0ce4449011..285f92e5b2 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
@@ -26,7 +26,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.function.Supplier;
 
-import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.client.NamespaceNotFoundException;
 import org.apache.accumulo.core.client.TableNotFoundException;
@@ -106,7 +105,7 @@ public class SecurityOperation {
   protected SecurityOperation(ServerContext context, Authorizor author, Authenticator authent,
       PermissionHandler pm) {
     this.context = context;
-    zkUserPath = Constants.ZROOT + "/" + context.getInstanceID() + "/users";
+    zkUserPath = context.zkUserPath();
     zooCache = new ZooCache(context.getZooReader(), null);
     rootUserName = Suppliers.memoize(() -> new String(zooCache.get(zkUserPath), UTF_8));
     authorizor = author;
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java
index 45104f3a78..1afd6c3442 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java
@@ -24,7 +24,6 @@ import java.util.Base64;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
 import org.apache.accumulo.core.client.security.tokens.KerberosToken;
@@ -63,7 +62,7 @@ public class KerberosAuthenticator implements Authenticator {
     zooCache = new ZooCache(context.getZooReader(), null);
     impersonation = new UserImpersonation(context.getConfiguration());
     zkAuthenticator.initialize(context);
-    zkUserPath = Constants.ZROOT + "/" + context.getInstanceID() + "/users";
+    zkUserPath = context.zkUserPath();
   }
 
   @Override
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java
index 86fa5a0688..a2895b2ed0 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java
@@ -26,7 +26,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 
-import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.AccumuloException;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
@@ -46,14 +45,14 @@ public final class ZKAuthenticator implements Authenticator {
   private static final Logger log = LoggerFactory.getLogger(ZKAuthenticator.class);
 
   private ServerContext context;
-  private String ZKUserPath;
+  private String zkUserPath;
   private ZooCache zooCache;
 
   @Override
   public void initialize(ServerContext context) {
     this.context = context;
     zooCache = new ZooCache(context.getZooReader(), null);
-    ZKUserPath = Constants.ZROOT + "/" + context.getInstanceID() + "/users";
+    zkUserPath = context.zkUserPath();
   }
 
   /**
@@ -63,7 +62,7 @@ public final class ZKAuthenticator implements Authenticator {
     List<String> outdatedUsers = new LinkedList<>();
     try {
       listUsers().forEach(user -> {
-        String zpath = ZKUserPath + "/" + user;
+        String zpath = zkUserPath + "/" + user;
         byte[] zkData = zooCache.get(zpath);
         if (ZKSecurityTool.isOutdatedPass(zkData)) {
           outdatedUsers.add(user);
@@ -90,13 +89,13 @@ public final class ZKAuthenticator implements Authenticator {
       ZooReaderWriter zoo = context.getZooReaderWriter();
       synchronized (zooCache) {
         zooCache.clear();
-        if (zoo.exists(ZKUserPath)) {
-          zoo.recursiveDelete(ZKUserPath, NodeMissingPolicy.SKIP);
-          log.info("Removed {}/ from zookeeper", ZKUserPath);
+        if (zoo.exists(zkUserPath)) {
+          zoo.recursiveDelete(zkUserPath, NodeMissingPolicy.SKIP);
+          log.info("Removed {}/ from zookeeper", zkUserPath);
         }
 
         // prep parent node of users with root username
-        zoo.putPersistentData(ZKUserPath, principal.getBytes(UTF_8), NodeExistsPolicy.FAIL);
+        zoo.putPersistentData(zkUserPath, principal.getBytes(UTF_8), NodeExistsPolicy.FAIL);
 
         constructUser(principal, ZKSecurityTool.createPass(token));
       }
@@ -115,13 +114,13 @@ public final class ZKAuthenticator implements Authenticator {
     synchronized (zooCache) {
       zooCache.clear();
       ZooReaderWriter zoo = context.getZooReaderWriter();
-      zoo.putPrivatePersistentData(ZKUserPath + "/" + user, pass, NodeExistsPolicy.FAIL);
+      zoo.putPrivatePersistentData(zkUserPath + "/" + user, pass, NodeExistsPolicy.FAIL);
     }
   }
 
   @Override
   public Set<String> listUsers() {
-    return new TreeSet<>(zooCache.getChildren(ZKUserPath));
+    return new TreeSet<>(zooCache.getChildren(zkUserPath));
   }
 
   @Override
@@ -152,7 +151,7 @@ public final class ZKAuthenticator implements Authenticator {
     try {
       synchronized (zooCache) {
         zooCache.clear();
-        context.getZooReaderWriter().recursiveDelete(ZKUserPath + "/" + user,
+        context.getZooReaderWriter().recursiveDelete(zkUserPath + "/" + user,
             NodeMissingPolicy.FAIL);
       }
     } catch (InterruptedException e) {
@@ -177,8 +176,8 @@ public final class ZKAuthenticator implements Authenticator {
     if (userExists(principal)) {
       try {
         synchronized (zooCache) {
-          zooCache.clear(ZKUserPath + "/" + principal);
-          context.getZooReaderWriter().putPrivatePersistentData(ZKUserPath + "/" + principal,
+          zooCache.clear(zkUserPath + "/" + principal);
+          context.getZooReaderWriter().putPrivatePersistentData(zkUserPath + "/" + principal,
               ZKSecurityTool.createPass(pt.getPassword()), NodeExistsPolicy.OVERWRITE);
         }
       } catch (KeeperException e) {
@@ -199,7 +198,7 @@ public final class ZKAuthenticator implements Authenticator {
 
   @Override
   public boolean userExists(String user) {
-    return zooCache.get(ZKUserPath + "/" + user) != null;
+    return zooCache.get(zkUserPath + "/" + user) != null;
   }
 
   @Override
@@ -215,7 +214,7 @@ public final class ZKAuthenticator implements Authenticator {
     }
     PasswordToken pt = (PasswordToken) token;
     byte[] zkData;
-    String zpath = ZKUserPath + "/" + principal;
+    String zpath = zkUserPath + "/" + principal;
     zkData = zooCache.get(zpath);
     boolean result = authenticateUser(principal, pt, zkData);
     if (!result) {
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java
index e23b13e25e..65a6cbc486 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java
@@ -43,19 +43,19 @@ public class ZKAuthorizor implements Authorizor {
   private final String ZKUserAuths = "/Authorizations";
 
   private ServerContext context;
-  private String ZKUserPath;
+  private String zkUserPath;
   private ZooCache zooCache;
 
   @Override
   public void initialize(ServerContext context) {
     this.context = context;
     zooCache = new ZooCache(context.getZooReader(), null);
-    ZKUserPath = ZKSecurityTool.getInstancePath(context.getInstanceID()) + "/users";
+    zkUserPath = context.zkUserPath();
   }
 
   @Override
   public Authorizations getCachedUserAuthorizations(String user) {
-    byte[] authsBytes = zooCache.get(ZKUserPath + "/" + user + ZKUserAuths);
+    byte[] authsBytes = zooCache.get(zkUserPath + "/" + user + ZKUserAuths);
     if (authsBytes != null) {
       return ZKSecurityTool.convertAuthorizations(authsBytes);
     }
@@ -75,12 +75,12 @@ public class ZKAuthorizor implements Authorizor {
     // create the root user with no record-level authorizations
     try {
       // prep parent node of users with root username
-      if (!zoo.exists(ZKUserPath)) {
-        zoo.putPersistentData(ZKUserPath, rootuser.getBytes(UTF_8), NodeExistsPolicy.FAIL);
+      if (!zoo.exists(zkUserPath)) {
+        zoo.putPersistentData(zkUserPath, rootuser.getBytes(UTF_8), NodeExistsPolicy.FAIL);
       }
 
       initUser(rootuser);
-      zoo.putPersistentData(ZKUserPath + "/" + rootuser + ZKUserAuths,
+      zoo.putPersistentData(zkUserPath + "/" + rootuser + ZKUserAuths,
           ZKSecurityTool.convertAuthorizations(Authorizations.EMPTY), NodeExistsPolicy.FAIL);
     } catch (KeeperException | InterruptedException e) {
       log.error("{}", e.getMessage(), e);
@@ -92,7 +92,7 @@ public class ZKAuthorizor implements Authorizor {
   public void initUser(String user) throws AccumuloSecurityException {
     ZooReaderWriter zoo = context.getZooReaderWriter();
     try {
-      zoo.putPersistentData(ZKUserPath + "/" + user, new byte[0], NodeExistsPolicy.SKIP);
+      zoo.putPersistentData(zkUserPath + "/" + user, new byte[0], NodeExistsPolicy.SKIP);
     } catch (KeeperException e) {
       log.error("{}", e.getMessage(), e);
       throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
@@ -107,8 +107,8 @@ public class ZKAuthorizor implements Authorizor {
     try {
       synchronized (zooCache) {
         ZooReaderWriter zoo = context.getZooReaderWriter();
-        zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserAuths, NodeMissingPolicy.SKIP);
-        zooCache.clear(ZKUserPath + "/" + user);
+        zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserAuths, NodeMissingPolicy.SKIP);
+        zooCache.clear(zkUserPath + "/" + user);
       }
     } catch (InterruptedException e) {
       log.error("{}", e.getMessage(), e);
@@ -129,7 +129,7 @@ public class ZKAuthorizor implements Authorizor {
     try {
       synchronized (zooCache) {
         zooCache.clear();
-        context.getZooReaderWriter().putPersistentData(ZKUserPath + "/" + user + ZKUserAuths,
+        context.getZooReaderWriter().putPersistentData(zkUserPath + "/" + user + ZKUserAuths,
             ZKSecurityTool.convertAuthorizations(authorizations), NodeExistsPolicy.OVERWRITE);
       }
     } catch (KeeperException e) {
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
index ea306f1516..59c1864fbb 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
@@ -55,7 +55,7 @@ public class ZKPermHandler implements PermissionHandler {
   private static final Logger log = LoggerFactory.getLogger(ZKPermHandler.class);
 
   private ZooReaderWriter zoo;
-  private String ZKUserPath;
+  private String zkUserPath;
   private String ZKTablePath;
   private String ZKNamespacePath;
   private ZooCache zooCache;
@@ -68,7 +68,7 @@ public class ZKPermHandler implements PermissionHandler {
     zooCache = new ZooCache(context.getZooReader(), null);
     zoo = context.getZooReaderWriter();
     InstanceId instanceId = context.getInstanceID();
-    ZKUserPath = ZKSecurityTool.getInstancePath(instanceId) + "/users";
+    zkUserPath = context.zkUserPath();
     ZKTablePath = ZKSecurityTool.getInstancePath(instanceId) + "/tables";
     ZKNamespacePath = ZKSecurityTool.getInstancePath(instanceId) + "/namespaces";
   }
@@ -78,7 +78,7 @@ public class ZKPermHandler implements PermissionHandler {
       throws TableNotFoundException {
     byte[] serializedPerms;
     try {
-      String path = ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table;
+      String path = zkUserPath + "/" + user + ZKUserTablePerms + "/" + table;
       zoo.sync(path);
       serializedPerms = zoo.getData(path);
     } catch (KeeperException e) {
@@ -115,7 +115,7 @@ public class ZKPermHandler implements PermissionHandler {
 
   @Override
   public boolean hasCachedTablePermission(String user, String table, TablePermission permission) {
-    byte[] serializedPerms = zooCache.get(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table);
+    byte[] serializedPerms = zooCache.get(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table);
     if (serializedPerms != null) {
       return ZKSecurityTool.convertTablePermissions(serializedPerms).contains(permission);
     }
@@ -127,7 +127,7 @@ public class ZKPermHandler implements PermissionHandler {
       NamespacePermission permission) throws NamespaceNotFoundException {
     byte[] serializedPerms;
     try {
-      String path = ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace;
+      String path = zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace;
       zoo.sync(path);
       serializedPerms = zoo.getData(path);
     } catch (KeeperException e) {
@@ -167,7 +167,7 @@ public class ZKPermHandler implements PermissionHandler {
   public boolean hasCachedNamespacePermission(String user, String namespace,
       NamespacePermission permission) {
     byte[] serializedPerms =
-        zooCache.get(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
+        zooCache.get(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
     if (serializedPerms != null) {
       return ZKSecurityTool.convertNamespacePermissions(serializedPerms).contains(permission);
     }
@@ -178,7 +178,7 @@ public class ZKPermHandler implements PermissionHandler {
   public void grantSystemPermission(String user, SystemPermission permission)
       throws AccumuloSecurityException {
     try {
-      byte[] permBytes = zooCache.get(ZKUserPath + "/" + user + ZKUserSysPerms);
+      byte[] permBytes = zooCache.get(zkUserPath + "/" + user + ZKUserSysPerms);
       Set<SystemPermission> perms;
       if (permBytes == null) {
         perms = new TreeSet<>();
@@ -189,7 +189,7 @@ public class ZKPermHandler implements PermissionHandler {
       if (perms.add(permission)) {
         synchronized (zooCache) {
           zooCache.clear();
-          zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserSysPerms,
+          zoo.putPersistentData(zkUserPath + "/" + user + ZKUserSysPerms,
               ZKSecurityTool.convertSystemPermissions(perms), NodeExistsPolicy.OVERWRITE);
         }
       }
@@ -206,7 +206,7 @@ public class ZKPermHandler implements PermissionHandler {
   public void grantTablePermission(String user, String table, TablePermission permission)
       throws AccumuloSecurityException {
     Set<TablePermission> tablePerms;
-    byte[] serializedPerms = zooCache.get(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table);
+    byte[] serializedPerms = zooCache.get(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table);
     if (serializedPerms != null) {
       tablePerms = ZKSecurityTool.convertTablePermissions(serializedPerms);
     } else {
@@ -216,8 +216,8 @@ public class ZKPermHandler implements PermissionHandler {
     try {
       if (tablePerms.add(permission)) {
         synchronized (zooCache) {
-          zooCache.clear(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table);
-          zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table,
+          zooCache.clear(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table);
+          zoo.putPersistentData(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table,
               ZKSecurityTool.convertTablePermissions(tablePerms), NodeExistsPolicy.OVERWRITE);
         }
       }
@@ -235,7 +235,7 @@ public class ZKPermHandler implements PermissionHandler {
       NamespacePermission permission) throws AccumuloSecurityException {
     Set<NamespacePermission> namespacePerms;
     byte[] serializedPerms =
-        zooCache.get(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
+        zooCache.get(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
     if (serializedPerms != null) {
       namespacePerms = ZKSecurityTool.convertNamespacePermissions(serializedPerms);
     } else {
@@ -245,8 +245,8 @@ public class ZKPermHandler implements PermissionHandler {
     try {
       if (namespacePerms.add(permission)) {
         synchronized (zooCache) {
-          zooCache.clear(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
-          zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
+          zooCache.clear(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
+          zoo.putPersistentData(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
               ZKSecurityTool.convertNamespacePermissions(namespacePerms),
               NodeExistsPolicy.OVERWRITE);
         }
@@ -263,7 +263,7 @@ public class ZKPermHandler implements PermissionHandler {
   @Override
   public void revokeSystemPermission(String user, SystemPermission permission)
       throws AccumuloSecurityException {
-    byte[] sysPermBytes = zooCache.get(ZKUserPath + "/" + user + ZKUserSysPerms);
+    byte[] sysPermBytes = zooCache.get(zkUserPath + "/" + user + ZKUserSysPerms);
 
     // User had no system permission, nothing to revoke.
     if (sysPermBytes == null) {
@@ -276,7 +276,7 @@ public class ZKPermHandler implements PermissionHandler {
       if (sysPerms.remove(permission)) {
         synchronized (zooCache) {
           zooCache.clear();
-          zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserSysPerms,
+          zoo.putPersistentData(zkUserPath + "/" + user + ZKUserSysPerms,
               ZKSecurityTool.convertSystemPermissions(sysPerms), NodeExistsPolicy.OVERWRITE);
         }
       }
@@ -292,7 +292,7 @@ public class ZKPermHandler implements PermissionHandler {
   @Override
   public void revokeTablePermission(String user, String table, TablePermission permission)
       throws AccumuloSecurityException {
-    byte[] serializedPerms = zooCache.get(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table);
+    byte[] serializedPerms = zooCache.get(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table);
 
     // User had no table permission, nothing to revoke.
     if (serializedPerms == null) {
@@ -304,10 +304,10 @@ public class ZKPermHandler implements PermissionHandler {
       if (tablePerms.remove(permission)) {
         zooCache.clear();
         if (tablePerms.isEmpty()) {
-          zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table,
+          zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table,
               NodeMissingPolicy.SKIP);
         } else {
-          zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table,
+          zoo.putPersistentData(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table,
               ZKSecurityTool.convertTablePermissions(tablePerms), NodeExistsPolicy.OVERWRITE);
         }
       }
@@ -324,7 +324,7 @@ public class ZKPermHandler implements PermissionHandler {
   public void revokeNamespacePermission(String user, String namespace,
       NamespacePermission permission) throws AccumuloSecurityException {
     byte[] serializedPerms =
-        zooCache.get(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
+        zooCache.get(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace);
 
     // User had no namespace permission, nothing to revoke.
     if (serializedPerms == null) {
@@ -337,10 +337,10 @@ public class ZKPermHandler implements PermissionHandler {
       if (namespacePerms.remove(permission)) {
         zooCache.clear();
         if (namespacePerms.isEmpty()) {
-          zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
+          zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
               NodeMissingPolicy.SKIP);
         } else {
-          zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
+          zoo.putPersistentData(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
               ZKSecurityTool.convertNamespacePermissions(namespacePerms),
               NodeExistsPolicy.OVERWRITE);
         }
@@ -359,8 +359,8 @@ public class ZKPermHandler implements PermissionHandler {
     try {
       synchronized (zooCache) {
         zooCache.clear();
-        for (String user : zooCache.getChildren(ZKUserPath)) {
-          zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table,
+        for (String user : zooCache.getChildren(zkUserPath)) {
+          zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table,
               NodeMissingPolicy.SKIP);
         }
       }
@@ -378,8 +378,8 @@ public class ZKPermHandler implements PermissionHandler {
     try {
       synchronized (zooCache) {
         zooCache.clear();
-        for (String user : zooCache.getChildren(ZKUserPath)) {
-          zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
+        for (String user : zooCache.getChildren(zkUserPath)) {
+          zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
               NodeMissingPolicy.SKIP);
         }
       }
@@ -413,12 +413,12 @@ public class ZKPermHandler implements PermissionHandler {
 
     try {
       // prep parent node of users with root username
-      if (!zoo.exists(ZKUserPath)) {
-        zoo.putPersistentData(ZKUserPath, rootuser.getBytes(UTF_8), NodeExistsPolicy.FAIL);
+      if (!zoo.exists(zkUserPath)) {
+        zoo.putPersistentData(zkUserPath, rootuser.getBytes(UTF_8), NodeExistsPolicy.FAIL);
       }
 
       initUser(rootuser);
-      zoo.putPersistentData(ZKUserPath + "/" + rootuser + ZKUserSysPerms,
+      zoo.putPersistentData(zkUserPath + "/" + rootuser + ZKUserSysPerms,
           ZKSecurityTool.convertSystemPermissions(rootPerms), NodeExistsPolicy.FAIL);
       for (Entry<TableId,Set<TablePermission>> entry : tablePerms.entrySet()) {
         createTablePerm(rootuser, entry.getKey(), entry.getValue());
@@ -435,10 +435,10 @@ public class ZKPermHandler implements PermissionHandler {
   @Override
   public void initUser(String user) throws AccumuloSecurityException {
     try {
-      zoo.putPersistentData(ZKUserPath + "/" + user, new byte[0], NodeExistsPolicy.SKIP);
-      zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserTablePerms, new byte[0],
+      zoo.putPersistentData(zkUserPath + "/" + user, new byte[0], NodeExistsPolicy.SKIP);
+      zoo.putPersistentData(zkUserPath + "/" + user + ZKUserTablePerms, new byte[0],
           NodeExistsPolicy.SKIP);
-      zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserNamespacePerms, new byte[0],
+      zoo.putPersistentData(zkUserPath + "/" + user + ZKUserNamespacePerms, new byte[0],
           NodeExistsPolicy.SKIP);
     } catch (KeeperException e) {
       log.error("{}", e.getMessage(), e);
@@ -457,7 +457,7 @@ public class ZKPermHandler implements PermissionHandler {
       throws KeeperException, InterruptedException {
     synchronized (zooCache) {
       zooCache.clear();
-      zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserTablePerms + "/" + table,
+      zoo.putPersistentData(zkUserPath + "/" + user + ZKUserTablePerms + "/" + table,
           ZKSecurityTool.convertTablePermissions(perms), NodeExistsPolicy.FAIL);
     }
   }
@@ -470,7 +470,7 @@ public class ZKPermHandler implements PermissionHandler {
       Set<NamespacePermission> perms) throws KeeperException, InterruptedException {
     synchronized (zooCache) {
       zooCache.clear();
-      zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
+      zoo.putPersistentData(zkUserPath + "/" + user + ZKUserNamespacePerms + "/" + namespace,
           ZKSecurityTool.convertNamespacePermissions(perms), NodeExistsPolicy.FAIL);
     }
   }
@@ -479,10 +479,10 @@ public class ZKPermHandler implements PermissionHandler {
   public void cleanUser(String user) throws AccumuloSecurityException {
     try {
       synchronized (zooCache) {
-        zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserSysPerms, NodeMissingPolicy.SKIP);
-        zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserTablePerms, NodeMissingPolicy.SKIP);
-        zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserNamespacePerms, NodeMissingPolicy.SKIP);
-        zooCache.clear(ZKUserPath + "/" + user);
+        zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserSysPerms, NodeMissingPolicy.SKIP);
+        zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserTablePerms, NodeMissingPolicy.SKIP);
+        zoo.recursiveDelete(zkUserPath + "/" + user + ZKUserNamespacePerms, NodeMissingPolicy.SKIP);
+        zooCache.clear(zkUserPath + "/" + user);
       }
     } catch (InterruptedException e) {
       log.error("{}", e.getMessage(), e);
@@ -501,7 +501,7 @@ public class ZKPermHandler implements PermissionHandler {
   public boolean hasSystemPermission(String user, SystemPermission permission) {
     byte[] perms;
     try {
-      String path = ZKUserPath + "/" + user + ZKUserSysPerms;
+      String path = zkUserPath + "/" + user + ZKUserSysPerms;
       zoo.sync(path);
       perms = zoo.getData(path);
     } catch (KeeperException e) {
@@ -523,7 +523,7 @@ public class ZKPermHandler implements PermissionHandler {
 
   @Override
   public boolean hasCachedSystemPermission(String user, SystemPermission permission) {
-    byte[] perms = zooCache.get(ZKUserPath + "/" + user + ZKUserSysPerms);
+    byte[] perms = zooCache.get(zkUserPath + "/" + user + ZKUserSysPerms);
     if (perms == null) {
       return false;
     }
diff --git a/server/base/src/test/java/org/apache/accumulo/server/MockServerContext.java b/server/base/src/test/java/org/apache/accumulo/server/MockServerContext.java
index c35a143ae7..801e0c301c 100644
--- a/server/base/src/test/java/org/apache/accumulo/server/MockServerContext.java
+++ b/server/base/src/test/java/org/apache/accumulo/server/MockServerContext.java
@@ -49,6 +49,7 @@ public class MockServerContext {
     var sc = get();
     expect(sc.getZooKeeperRoot()).andReturn("/accumulo/" + instanceID).anyTimes();
     expect(sc.getInstanceID()).andReturn(instanceID).anyTimes();
+    expect(sc.zkUserPath()).andReturn("/accumulo/" + instanceID + "/users").anyTimes();
     expect(sc.getZooKeepers()).andReturn(zk).anyTimes();
     expect(sc.getZooKeepersSessionTimeOut()).andReturn(zkTimeout).anyTimes();
     return sc;
diff --git a/test/src/main/java/org/apache/accumulo/test/conf/util/LegacyPropData.java b/test/src/main/java/org/apache/accumulo/test/conf/util/LegacyPropData.java
index 19bb1cbc74..e00035a7df 100644
--- a/test/src/main/java/org/apache/accumulo/test/conf/util/LegacyPropData.java
+++ b/test/src/main/java/org/apache/accumulo/test/conf/util/LegacyPropData.java
@@ -61,7 +61,7 @@ public class LegacyPropData {
     names.add(new PropNode(zkRoot + "/table_locks", null));
     names.add(new PropNode(zkRoot + "/tables", null));
     names.add(new PropNode(zkRoot + "/tservers", null));
-    names.add(new PropNode(zkRoot + "/users", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS, null));
     names.add(new PropNode(zkRoot + "/wals", null));
     names.add(new PropNode(zkRoot + "/bulk_failed_copyq/locks", null));
     names.add(new PropNode(zkRoot + "/config/master.bulk.retries", "4"));
@@ -340,21 +340,21 @@ public class LegacyPropData {
         new PropNode(zkRoot + "/tables/7/conf/table.iterator.scan.vers.opt.maxVersions", null));
     names.add(new PropNode(zkRoot + "/tservers/localhost:11000", null));
     names.add(new PropNode(zkRoot + "/tservers/localhost:11000/zlock-0000000000", null));
-    names.add(new PropNode(zkRoot + "/users/root", null));
-    names.add(new PropNode(zkRoot + "/users/root/Authorizations", null));
-    names.add(new PropNode(zkRoot + "/users/root/Namespaces", null));
-    names.add(new PropNode(zkRoot + "/users/root/System", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables", null));
-    names.add(new PropNode(zkRoot + "/users/root/Namespaces/+accumulo", null));
-    names.add(new PropNode(zkRoot + "/users/root/Namespaces/2", null));
-    names.add(new PropNode(zkRoot + "/users/root/Namespaces/3", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables/!0", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables/+r", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables/1", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables/4", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables/5", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables/6", null));
-    names.add(new PropNode(zkRoot + "/users/root/Tables/7", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Authorizations", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Namespaces", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/System", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Namespaces/+accumulo", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Namespaces/2", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Namespaces/3", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables/!0", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables/+r", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables/1", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables/4", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables/5", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables/6", null));
+    names.add(new PropNode(zkRoot + Constants.ZUSERS + "/root/Tables/7", null));
     names.add(new PropNode(zkRoot + "/wals/localhost:11000[10000c3202e0003]", null));
     names.add(new PropNode(
         zkRoot + "/wals/localhost:11000[10000c3202e0003]/0fef8f3b-d02d-413b-9a27-f1710812b216",