Repository: zookeeper
Updated Branches:
refs/heads/branch-3.5 b9ff4935b -> 822e51a01
ZOOKEEPER-1782: Let a SASL super user be super
Author: Robert Evans <evans@yahoo-inc.com>
Reviewers: Michael Han <hanm@apache.org>, Mohammad Arshad <arshad@apache.org>
Closes #282 from revans2/ZOOKEEPER-1782
(cherry picked from commit fb267672d219c73c0cf2527fafebc1a0b17d3bee)
Signed-off-by: Michael Han <hanm@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo
Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/822e51a0
Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/822e51a0
Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/822e51a0
Branch: refs/heads/branch-3.5
Commit: 822e51a01201fc56e810aacf36f828cf226c45e3
Parents: b9ff493
Author: Robert Evans <evans@yahoo-inc.com>
Authored: Fri Jun 23 09:39:05 2017 -0700
Committer: Michael Han <hanm@apache.org>
Committed: Fri Jun 23 09:39:26 2017 -0700
----------------------------------------------------------------------
.../content/xdocs/zookeeperAdmin.xml | 13 ++
.../zookeeper/server/ZooKeeperServer.java | 4 +
.../server/auth/SASLAuthenticationProvider.java | 5 -
.../zookeeper/test/SaslSuperUserTest.java | 136 +++++++++++++++++++
4 files changed, 153 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/822e51a0/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml
----------------------------------------------------------------------
diff --git a/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml b/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml
index d0bb930..c4eaf87 100644
--- a/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml
+++ b/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml
@@ -1260,6 +1260,19 @@ server.3=zoo3:2888:3888</programlisting>
</varlistentry>
<varlistentry>
+ <term>zookeeper.superUser</term>
+ <listitem>
+ <para>(Java system property: <emphasis
+ role="bold">zookeeper.superUser</emphasis>)</para>
+
+ <para>Similar to <emphasis role="bold">zookeeper.X509AuthenticationProvider.superUser</emphasis>
+ but is generic for SASL based logins. It stores the name of
+ a user that can access the znode hierarchy as a "super" user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ssl.keyStore.location and ssl.keyStore.password</term>
<listitem>
<para>(Java system properties: <emphasis role="bold">
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/822e51a0/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java b/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
index c1d62f8..f378a43 100644
--- a/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
+++ b/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
@@ -1131,6 +1131,10 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider
{
String authorizationID = saslServer.getAuthorizationID();
LOG.info("adding SASL authorization for authorizationID: " + authorizationID);
cnxn.addAuthInfo(new Id("sasl",authorizationID));
+ if (System.getProperty("zookeeper.superUser") != null &&
+ authorizationID.equals(System.getProperty("zookeeper.superUser")))
{
+ cnxn.addAuthInfo(new Id("super", ""));
+ }
}
}
catch (SaslException e) {
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/822e51a0/src/java/main/org/apache/zookeeper/server/auth/SASLAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/auth/SASLAuthenticationProvider.java
b/src/java/main/org/apache/zookeeper/server/auth/SASLAuthenticationProvider.java
index 4690e69..1f60b39 100644
--- a/src/java/main/org/apache/zookeeper/server/auth/SASLAuthenticationProvider.java
+++ b/src/java/main/org/apache/zookeeper/server/auth/SASLAuthenticationProvider.java
@@ -38,11 +38,6 @@ public class SASLAuthenticationProvider implements AuthenticationProvider
{
}
public boolean matches(String id,String aclExpr) {
- if (System.getProperty("zookeeper.superUser") != null) {
- if (id.equals(System.getProperty("zookeeper.superUser")) || id.equals(aclExpr))
{
- return true;
- }
- }
if ((id.equals("super") || id.equals(aclExpr))) {
return true;
}
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/822e51a0/src/java/test/org/apache/zookeeper/test/SaslSuperUserTest.java
----------------------------------------------------------------------
diff --git a/src/java/test/org/apache/zookeeper/test/SaslSuperUserTest.java b/src/java/test/org/apache/zookeeper/test/SaslSuperUserTest.java
new file mode 100644
index 0000000..894c0f5
--- /dev/null
+++ b/src/java/test/org/apache/zookeeper/test/SaslSuperUserTest.java
@@ -0,0 +1,136 @@
+/**
+ * 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.zookeeper.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Perms;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
+import org.junit.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SaslSuperUserTest extends ClientBase {
+ private static Id otherSaslUser = new Id ("sasl", "joe");
+ private static Id otherDigestUser;
+ private static String oldAuthProvider;
+ private static String oldLoginConfig;
+ private static String oldSuperUser;
+
+ @BeforeClass
+ public static void setupStatic() throws Exception {
+ oldAuthProvider = System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
+
+ File tmpDir = createTmpDir();
+ File saslConfFile = new File(tmpDir, "jaas.conf");
+ FileWriter fwriter = new FileWriter(saslConfFile);
+
+ fwriter.write("" +
+ "Server {\n" +
+ " org.apache.zookeeper.server.auth.DigestLoginModule required\n"
+
+ " user_super_duper=\"test\";\n" +
+ "};\n" +
+ "Client {\n" +
+ " org.apache.zookeeper.server.auth.DigestLoginModule required\n" +
+ " username=\"super_duper\"\n" +
+ " password=\"test\";\n" +
+ "};" + "\n");
+ fwriter.close();
+ oldLoginConfig = System.setProperty("java.security.auth.login.config",saslConfFile.getAbsolutePath());
+ oldSuperUser = System.setProperty("zookeeper.superUser","super_duper");
+ otherDigestUser = new Id ("digest", DigestAuthenticationProvider.generateDigest("jack:jack"));
+ }
+
+ @AfterClass
+ public static void cleanupStatic() {
+ if (oldAuthProvider != null) {
+ System.setProperty("zookeeper.authProvider.1", oldAuthProvider);
+ } else {
+ System.clearProperty("zookeeper.authProvider.1");
+ }
+ oldAuthProvider = null;
+
+ if (oldLoginConfig != null) {
+ System.setProperty("java.security.auth.login.config", oldLoginConfig);
+ } else {
+ System.clearProperty("java.security.auth.login.config");
+ }
+ oldLoginConfig = null;
+
+ if (oldSuperUser != null) {
+ System.setProperty("zookeeper.superUser", oldSuperUser);
+ } else {
+ System.clearProperty("zookeeper.superUser");
+ }
+ oldSuperUser = null;
+ }
+
+ private AtomicInteger authFailed = new AtomicInteger(0);
+
+ @Override
+ protected TestableZooKeeper createClient(String hp)
+ throws IOException, InterruptedException
+ {
+ MyWatcher watcher = new MyWatcher();
+ return createClient(watcher, hp);
+ }
+
+ private class MyWatcher extends CountdownWatcher {
+ @Override
+ public synchronized void process(WatchedEvent event) {
+ if (event.getState() == KeeperState.AuthFailed) {
+ authFailed.incrementAndGet();
+ }
+ else {
+ super.process(event);
+ }
+ }
+ }
+
+ @Test
+ public void testSuperIsSuper() throws Exception {
+ ZooKeeper zk = createClient();
+ try {
+ zk.create("/digest_read", null, Arrays.asList(new ACL(Perms.READ, otherDigestUser)),
CreateMode.PERSISTENT);
+ zk.create("/digest_read/sub", null, Arrays.asList(new ACL(Perms.READ, otherDigestUser)),
CreateMode.PERSISTENT);
+ zk.create("/sasl_read", null, Arrays.asList(new ACL(Perms.READ, otherSaslUser)),
CreateMode.PERSISTENT);
+ zk.create("/sasl_read/sub", null, Arrays.asList(new ACL(Perms.READ, otherSaslUser)),
CreateMode.PERSISTENT);
+ zk.delete("/digest_read/sub", -1);
+ zk.delete("/digest_read", -1);
+ zk.delete("/sasl_read/sub", -1);
+ zk.delete("/sasl_read", -1);
+ //If the test failes it will most likely fail with a NoAuth exception before
it ever gets to this assertion
+ Assert.assertEquals(authFailed.get(), 0);
+ } finally {
+ zk.close();
+ }
+ }
+}
|