I did some more investigating on this issue. It looks like when you acquire a lock, it creates the path by doing: ourPath = client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path); When I do that manually where path is “/foo”, it actually doesn’t create “/foo” yet and instead creates something like "/_c_2235fc7d-f5e8-4c3a-bb24-27c610022aaa-foo0000000000”.
>From what I can tell, this has to do with the withprotection() and EPHEMERAL_SEQUENTIAL mode and is to prevent some kind of problem I don’t quite understand from the javadocs. In any case, I believe that something eventually must rename "/_c_2235fc7d-f5e8-4c3a-bb24-27c610022aaa-foo0000000000” to “/foo”. When I checked, "/_c_2235fc7d-f5e8-4c3a-bb24-27c610022aaa-foo0000000000” has the ACLs I set in the ACLProvider, so I’m thinking the problem must be happening when the znode is renamed. I’m not sure where/when that happens, but I’d guess its not using the ACLProvider and that’s why “/foo" has the default ACLs. Do you think this is the cause? Any idea on how to fix it or workaround it? thanks - Robert On Tue, Nov 5, 2013 at 1:58 PM, Robert Kanter <[email protected]> wrote: > I created the below test class using JUnit. It starts a TestingServerand > connects to it; then it creates a path directly to verify that the > custom ACLProvider is being applied. Then it tries to do the same with > an InterProcessReadWriteLock and fails the test because its using the > default ACLs. I used “ip” instead of “sasl” to keep things simpler. > > I did take a quick look at the Curator code and it seemed to be using the > ACLProvider through the CuratorFramework when using locks, but perhaps I > missed something (and I’m not super familiar with the codebase). > > Please take a look; thanks! > - Robert > > > import java.util.Collections; > import java.util.List; > import junit.framework.TestCase; > import org.apache.curator.RetryPolicy; > import org.apache.curator.framework.CuratorFramework; > import org.apache.curator.framework.CuratorFrameworkFactory; > import org.apache.curator.framework.api.ACLProvider; > import org.apache.curator.framework.recipes.locks.InterProcessMutex; > import > org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock; > import org.apache.curator.retry.ExponentialBackoffRetry; > import org.apache.curator.test.TestingServer; > import org.apache.zookeeper.ZooDefs; > import org.apache.zookeeper.data.ACL; > import org.apache.zookeeper.data.Id; > > public class TestLockACLs extends TestCase { > private TestingServer zkServer; > private CuratorFramework client; > private final List<ACL> acls = Collections.singletonList(new > ACL(ZooDefs.Perms.ALL, new Id("ip", "127.0.0.1"))); > > @Override > protected void setUp() throws Exception { > super.setUp(); > zkServer = new TestingServer(); > createClient(); > } > > @Override > protected void tearDown() throws Exception { > super.tearDown(); > client.close(); > zkServer.stop(); > zkServer.close(); > } > > private void createClient() throws Exception { > RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); > String zkConnectionString = zkServer.getConnectString(); > String zkNamespace = "ns"; > client = CuratorFrameworkFactory.builder() > .namespace(zkNamespace) > > .connectString(zkConnectionString) > .retryPolicy(retryPolicy) > .aclProvider(new > MyACLProvider()) > .build(); > client.start(); > } > > public void testLockACLs() throws Exception { > // Create a path directly and verify that MyACLProvider is being > used > client.create().forPath("/foo"); > assertNotNull(client.checkExists().forPath("/foo")); > assertEquals(ZooDefs.Perms.ALL, > client.getACL().forPath("/foo").get(0).getPerms()); > assertEquals("ip", > client.getACL().forPath("/foo").get(0).getId().getScheme()); > assertEquals("127.0.0.1", > client.getACL().forPath("/foo").get(0).getId().getId()); > > // Now try creating a lock and we'll see that it incorrectly has > the default world ACLs > // and doesn't seem to be using MyACLProvider > InterProcessReadWriteLock lock = new > InterProcessReadWriteLock(client, "/bar"); > InterProcessMutex writeLock = lock.writeLock(); > writeLock.acquire(); > assertNotNull(client.checkExists().forPath("/bar")); > assertEquals(ZooDefs.Perms.ALL, > client.getACL().forPath("/bar").get(0).getPerms()); > assertEquals("ip", > client.getACL().forPath("/bar").get(0).getId().getScheme()); > assertEquals("127.0.0.1", > client.getACL().forPath("/bar").get(0).getId().getId()); > } > > public class MyACLProvider implements ACLProvider { > > @Override > public List<ACL> getDefaultAcl() { > return acls; > } > > @Override > public List<ACL> getAclForPath(String path) { > return acls; > } > } > } > > > On Mon, Nov 4, 2013 at 6:10 PM, Jordan Zimmerman < > [email protected]> wrote: > >> The ACLProvider should be called for every node created. It’s not getting >> called? Can you produce a test that shows this? >> >> -Jordan >> >> On Nov 4, 2013, at 5:57 PM, Robert Kanter <[email protected]> wrote: >> >> I have everything working now except for one thing: >> The ACLProvider doesn’t seem to be used for the locks (Curator’s >> InterProcessReadWriteLock); they are always created with the default >> fully open ACLs. I know the ACLProvider is correct now because the >> service discovery is using it and znodes created by it have the correct >> ACLs. InterProcessReadWriteLock’s constructor takes in the >> CuratorFramework object, which has the ACLProvider set. >> >> Any ideas? >> This sounds like it could be a Curator bug :( >> I’m not familiar with Curator’s codebase, but I’ll try to take a look and >> see if I can figure it out. >> >> thanks >> - Robert >> >> >> >> On Mon, Nov 4, 2013 at 1:09 PM, Robert Kanter <[email protected]>wrote: >> >>> I don’t have it 100% working yet, but I’ve figured out a lot more, so I >>> thought I’d share in case anyone else runs into this: >>> >>> The ZooDefs.Ids.CREATOR_ALL_ACL predefined ACL that I was trying to use >>> is for the “auth” scheme. For SASL/Kerberos, we want “sasl”. The >>> javadoc for the predefined one wasn’t very clear on that; I had to look at >>> the code. Using this is working: >>> Collections.singletonList(new ACL(Perms.ALL, new Id("sasl", principal))); >>> >>> I was also able to find answers to the three questions I asked: >>> 1) Yes; looking through the code, its definitely grabbing the >>> ACLProvider and using it. >>> 2) Yes; I think the only way to do this is to recursively travel through >>> the znodes under /oozie and apply the ACL on starting up Oozie. We >>> should only have to do this if previously it was setup without security and >>> has since been reconfigured to use security; so we should only have to do >>> this once. I can probably have a znode as a flag that states if >>> everything has ACLs or not to make it more efficient >>> 3) It doesn’t look like it; I’ll have to get the ZK client and do it >>> from outside Curator >>> >>> >>> - Robert >>> >>> >>> On Mon, Oct 28, 2013 at 5:47 PM, Jordan Zimmerman < >>> [email protected]> wrote: >>> >>>> I don’t have any experience with this. Curator doesn’t do much - it >>>> sets up the ACL as the CLI options dictate. I do know that you also have to >>>> do work on the server side to make this work. >>>> >>>> -JZ >>>> >>>> On Oct 24, 2013, at 4:58 PM, Robert Kanter <[email protected]> >>>> wrote: >>>> >>>> Hi, >>>> >>>> Is there any documentation on using an ACLProvider and/or Kerberos? >>>> >>>> From what I gathered at various sites, to use Kerberos, all I have to >>>> do is set the following properties before building the CuratorFramework >>>> client: >>>> System.setProperty("java.security.auth.login.config", >>>> "/path/to/jaasConfFile"); >>>> >>>> System.setProperty("zookeeper.authProvider.1","org.apache.zookeeper.server.auth.SASLAuthenticationProvider"); >>>> System.setProperty(ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY, >>>> "Client"); >>>> Looking at the logs for the client and server, this appears to be >>>> working properly and my program is connecting to ZooKeeper using Kerberos. >>>> >>>> The problem I'm having is with the ACLs. >>>> >>>> I'd like to set the ACLs so that only the Kerberos user running the >>>> program can do anything. From what I can tell, if I specify an >>>> ACLProvider, then Curator will automatically use it for setting ACLs >>>> on all paths. So, an ACLProvider like the following should do what I >>>> want: >>>> public class CreatorACLProvider implements ACLProvider { >>>> @Override >>>> public List<ACL> getDefaultAcl() { >>>> return ZooDefs.Ids.CREATOR_ALL_ACL; >>>> } >>>> @Override >>>> public List<ACL> getAclForPath(String path) { >>>> return ZooDefs.Ids.CREATOR_ALL_ACL; >>>> } >>>> } >>>> Then I would just do this: >>>> client = CuratorFrameworkFactory.builder() >>>> .namespace(zkNamespace) >>>> .connectString(zkConnectionString) >>>> .retryPolicy(retryPolicy) >>>> .aclProvider(new CreatorACLProvider()) >>>> .build(); >>>> client.start(); >>>> >>>> However, this doesn't seem to be working. The zkcli returns this (on a >>>> newly created znode): >>>> [zk: localhost:2181(CONNECTED) 8] getAcl >>>> /oozie/locks/0000000-131024162150146-oozie-oozi-W >>>> 'world,'anyone >>>> : Cdr. >>>> Is there something that I missed? >>>> >>>> A few other questions: >>>> 1) Will the ACLProvider cause the ACLs to be applied to znodes created >>>> by the Curator recipes? (e.g. InterProcessReadWriteLock, >>>> ServiceDiscovery, etc). If not, then how should I go about setting >>>> the ACLs for these znodes? >>>> 2) I'm guessing that the ACLProvider is only applied when creating the >>>> znode, right; so existing znodes from before I added the ACLProviderwon't >>>> have the ACLs I want, right? What would be the best way to apply the >>>> ACLs to any existing znodes that don't have it set? (My goal is to have >>>> all znodes under /oozie have the CREATOR_ALL_ACL) >>>> 3) Is there a way to set the ACLs on the namespace itself (i.e. /oozie)? >>>> The methods that take a path (and automatically prepend the namespace) >>>> don't allow simply "/", so it seems like I'd have to use the ZooKeeper >>>> client directly to set ACLs manually on the namespace. Or would simply >>>> passing an empty string "" work? >>>> >>>> thanks >>>> - Robert >>>> >>>> >>>> >>> >> >> >
