/** * parse string into list of ACL * @param aclString * @return */ public static List<ACL> parse(String aclString) { List<ACL> acl; String acls[] = aclString.split(","); acl = new ArrayList<ACL>(); for (String a : acls) { int firstColon = a.indexOf(':'); int lastColon = a.lastIndexOf(':'); if (firstColon == -1 || lastColon == -1 || firstColon == lastColon) { System.err.println(a + " does not have the form scheme:id:perm"); continue; } ACL newAcl = new ACL(); newAcl.setId(new Id(a.substring(0, firstColon), a.substring( firstColon + 1, lastColon))); newAcl.setPerms(getPermFromString(a.substring(lastColon + 1))); acl.add(newAcl); } return acl; }
@Test public void testUserHomedirsPermissionsRestricted() throws Throwable { // test that the /users/$user permissions are restricted RMRegistryOperationsService rmRegistryOperations = startRMRegistryOperations(); // create Alice's dir, so it should have an ACL for Alice final String home = rmRegistryOperations.initUserRegistry(ALICE); List<ACL> acls = rmRegistryOperations.zkGetACLS(home); ACL aliceACL = null; for (ACL acl : acls) { LOG.info(RegistrySecurity.aclToString(acl)); Id id = acl.getId(); if (id.getScheme().equals(ZookeeperConfigOptions.SCHEME_SASL) && id.getId().startsWith(ALICE)) { aliceACL = acl; break; } } assertNotNull(aliceACL); assertEquals(RegistryAdminService.USER_HOMEDIR_ACL_PERMISSIONS, aliceACL.getPerms()); }
@Test(timeout = 10000) public void testReconfigEnabledWithAuthAndACL() throws InterruptedException { resetZKAdmin(); try { zkAdmin.addAuthInfo("digest", "super:test".getBytes()); ArrayList<ACL> acls = new ArrayList<ACL>( Collections.singletonList( new ACL(ZooDefs.Perms.WRITE, new Id("digest", "user:tl+z3z0vO6PfPfEENfLF96E6pM0="/* password is test */)))); zkAdmin.setACL(ZooDefs.CONFIG_NODE, acls, -1); resetZKAdmin(); zkAdmin.addAuthInfo("digest", "user:test".getBytes()); Assert.assertTrue(reconfigPort()); } catch (KeeperException e) { Assert.fail("Reconfig should not fail, but failed with exception : " + e.getMessage()); } }
private static List<ACL> parseACLs(String aclString) { List<ACL> acl; String acls[] = aclString.split(","); acl = new ArrayList<ACL>(); for (String a : acls) { int firstColon = a.indexOf(':'); int lastColon = a.lastIndexOf(':'); if (firstColon == -1 || lastColon == -1 || firstColon == lastColon) { System.err .println(a + " does not have the form scheme:id:perm"); continue; } ACL newAcl = new ACL(); newAcl.setId(new Id(a.substring(0, firstColon), a.substring( firstColon + 1, lastColon))); newAcl.setPerms(getPermFromString(a.substring(lastColon + 1))); acl.add(newAcl); } return acl; }
/** * Add a digest ACL * @param acl add ACL */ public boolean addDigestACL(ACL acl) { if (secureRegistry) { if (LOG.isDebugEnabled()) { LOG.debug("Added ACL {}", aclToString(acl)); } digestACLs.add(acl); return true; } else { if (LOG.isDebugEnabled()) { LOG.debug("Ignoring added ACL - registry is insecure{}", aclToString(acl)); } return false; } }
@Override public Stat setACL(String path, List<ACL> acl, int version) throws KeeperException, InterruptedException { int count = 0; do { try { return super.setACL(path, acl, version); } catch (KeeperException.ConnectionLossException e) { LoggerFactory.getLogger().warn( "ZooKeeper connection lost. Trying to reconnect."); Stat s = exists(path, false); if (s != null) { if (getACL(path, s).equals(acl)) { return s; } } else { return null; } } } while (!closed && (limit == -1 || count++ < limit)); return null; }
/** * Set the ACL for the node of the given path if such a node exists and the * given version matches the version of the node. Return the stat of the * node. * <p> * A KeeperException with error code KeeperException.NoNode will be thrown * if no node with the given path exists. * <p> * A KeeperException with error code KeeperException.BadVersion will be * thrown if the given version does not match the node's version. * * @param path * @param acl * @param version * @return the stat of the node. * @throws InterruptedException If the server transaction is interrupted. * @throws KeeperException If the server signals an error with a non-zero error code. * @throws org.apache.zookeeper.KeeperException.InvalidACLException If the acl is invalide. * @throws IllegalArgumentException if an invalid path is specified */ public Stat setACL(final String path, List<ACL> acl, int version) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.setACL); SetACLRequest request = new SetACLRequest(); request.setPath(serverPath); if (acl != null && acl.size() == 0) { throw new KeeperException.InvalidACLException(clientPath); } request.setAcl(acl); request.setVersion(version); SetACLResponse response = new SetACLResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, null); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } return response.getStat(); }
/** * The asynchronous version of setACL. * * @see #setACL(String, List, int) */ public void setACL(final String path, List<ACL> acl, int version, StatCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.setACL); SetACLRequest request = new SetACLRequest(); request.setPath(serverPath); request.setAcl(acl); request.setVersion(version); SetACLResponse response = new SetACLResponse(); cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, clientPath, serverPath, ctx, null); }
/** * On master start, we check the znode ACLs under the root directory and set the ACLs properly * if needed. If the cluster goes from an unsecure setup to a secure setup, this step is needed * so that the existing znodes created with open permissions are now changed with restrictive * perms. */ public void checkAndSetZNodeAcls() { if (!ZKUtil.isSecureZooKeeper(getConfiguration())) { LOG.info("not a secure deployment, proceeding"); return; } // Check the base znodes permission first. Only do the recursion if base znode's perms are not // correct. try { List<ACL> actualAcls = recoverableZooKeeper.getAcl(baseZNode, new Stat()); if (!isBaseZnodeAclSetup(actualAcls)) { LOG.info("setting znode ACLs"); setZnodeAclsRecursive(baseZNode); } } catch(KeeperException.NoNodeException nne) { return; } catch(InterruptedException ie) { interruptedException(ie); } catch (IOException|KeeperException e) { LOG.warn("Received exception while checking and setting zookeeper ACLs", e); } }
@Test public void testMultipleAddsAndRemove() { List<ACL> testACL = createACL("myid"); ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); Long aclId = cache.convertAcls(testACL); assertEquals(1, cache.size()); cache.convertAcls(testACL); assertEquals(1, cache.size()); List<ACL> testACL2 = createACL("anotherId"); cache.convertAcls(testACL2); cache.removeUsage(aclId); assertEquals(2, cache.size()); cache.removeUsage(aclId); assertEquals(1, cache.size()); Long newId = cache.convertAcls(testACL); assertFalse(aclId.equals(newId)); }
@Test public void testAddUsage() { List<ACL> testACL = createACL("myid"); ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); Long aclId = cache.convertAcls(testACL); assertEquals(1, cache.size()); cache.addUsage(aclId); assertEquals(1, cache.size()); cache.removeUsage(aclId); assertEquals(1, cache.size()); cache.removeUsage(aclId); assertEquals(0, cache.size()); }
@Override public Stat setACL(String path, List<ACL> acl, int aclVersion) throws KeeperException, InterruptedException { int count = 0; do { try { return super.setACL(path, acl, aclVersion); } catch (KeeperException.ConnectionLossException e) { LoggerFactory.getLogger().warn( "ZooKeeper connection lost. Trying to reconnect."); Stat s = exists(path, false); if (s != null) { if (getACL(path, s).equals(acl)) { return s; } } else { return null; } } } while (!closed && (limit == -1 || count++ < limit)); return null; }
/** * The asynchronous version of create. * * @see #create(String, byte[], List, CreateMode) */ public void create(final String path, byte data[], List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath, createMode.isSequential()); final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.create); CreateRequest request = new CreateRequest(); CreateResponse response = new CreateResponse(); ReplyHeader r = new ReplyHeader(); request.setData(data); request.setFlags(createMode.toFlag()); request.setPath(serverPath); request.setAcl(acl); cnxn.queuePacket(h, r, request, response, cb, clientPath, serverPath, ctx, null); }
/** * Given the {@link Configuration} and {@link ACL}s used (zkAcl) for * ZooKeeper access, construct the {@link ACL}s for the store's root node. * In the constructed {@link ACL}, all the users allowed by zkAcl are given * rwa access, while the current RM has exclude create-delete access. * * To be called only when HA is enabled and the configuration doesn't set ACL * for the root node. */ @VisibleForTesting @Private @Unstable protected List<ACL> constructZkRootNodeACL( Configuration conf, List<ACL> sourceACLs) throws NoSuchAlgorithmException { List<ACL> zkRootNodeAcl = new ArrayList<ACL>(); for (ACL acl : sourceACLs) { zkRootNodeAcl.add(new ACL( ZKUtil.removeSpecificPerms(acl.getPerms(), CREATE_DELETE_PERMS), acl.getId())); } zkRootNodeUsername = HAUtil.getConfValueForRMInstance( YarnConfiguration.RM_ADDRESS, YarnConfiguration.DEFAULT_RM_ADDRESS, conf); Id rmId = new Id(zkRootNodeAuthScheme, DigestAuthenticationProvider.generateDigest( zkRootNodeUsername + ":" + zkRootNodePassword)); zkRootNodeAcl.add(new ACL(CREATE_DELETE_PERMS, rmId)); return zkRootNodeAcl; }
@Test public void testUGILogin() throws Throwable { UserGroupInformation ugi = loginUGI(ZOOKEEPER, keytab_zk); RegistrySecurity.UgiInfo ugiInfo = new RegistrySecurity.UgiInfo(ugi); LOG.info("logged in as: {}", ugiInfo); assertTrue("security is not enabled: " + ugiInfo, UserGroupInformation.isSecurityEnabled()); assertTrue("login is keytab based: " + ugiInfo, ugi.isFromKeytab()); // now we are here, build a SASL ACL ACL acl = ugi.doAs(new PrivilegedExceptionAction<ACL>() { @Override public ACL run() throws Exception { return registrySecurity.createSaslACLFromCurrentUser(0); } }); assertEquals(ZOOKEEPER_REALM, acl.getId().getId()); assertEquals(ZookeeperConfigOptions.SCHEME_SASL, acl.getId().getScheme()); registrySecurity.addSystemACL(acl); }
@Test public void testCreateNode1() throws Exception { ACL aclIp = new ACL(ZooDefs.Perms.READ,new Id("ip","192.168.1.105")); ACL aclDigest = new ACL(ZooDefs.Perms.READ| ZooDefs.Perms.WRITE,new Id("digest", ZKBase64AuthUtils.getDigest("aric","123456"))); ArrayList<ACL> acls = new ArrayList<ACL>(); acls.add(aclIp);acls.add(aclDigest); String path= zkSyncService.createNode("/node_4", "123".getBytes(),acls, CreateMode.PERSISTENT); PrinterUtils.printELog(path + "" + ZKWatcher.getWatchedEvent()); }
public synchronized void serialize(OutputArchive oa) throws IOException { oa.writeInt(longKeyMap.size(), "map"); Set<Map.Entry<Long, List<ACL>>> set = longKeyMap.entrySet(); for (Map.Entry<Long, List<ACL>> val : set) { oa.writeLong(val.getKey(), "long"); List<ACL> aclList = val.getValue(); oa.startVector(aclList, "acls"); for (ACL acl : aclList) { acl.serialize(oa, "acl"); } oa.endVector(aclList, "acls"); } }
@Override protected void serviceInit(Configuration conf) throws Exception { conf = conf instanceof YarnConfiguration ? conf : new YarnConfiguration(conf); String zkQuorum = conf.get(YarnConfiguration.RM_ZK_ADDRESS); if (zkQuorum == null) { throw new YarnRuntimeException("Embedded automatic failover " + "is enabled, but " + YarnConfiguration.RM_ZK_ADDRESS + " is not set"); } String rmId = HAUtil.getRMHAId(conf); String clusterId = YarnConfiguration.getClusterId(conf); localActiveNodeInfo = createActiveNodeInfo(clusterId, rmId); String zkBasePath = conf.get(YarnConfiguration.AUTO_FAILOVER_ZK_BASE_PATH, YarnConfiguration.DEFAULT_AUTO_FAILOVER_ZK_BASE_PATH); String electionZNode = zkBasePath + "/" + clusterId; long zkSessionTimeout = conf.getLong(YarnConfiguration.RM_ZK_TIMEOUT_MS, YarnConfiguration.DEFAULT_RM_ZK_TIMEOUT_MS); List<ACL> zkAcls = RMZKUtils.getZKAcls(conf); List<ZKUtil.ZKAuthInfo> zkAuths = RMZKUtils.getZKAuths(conf); int maxRetryNum = conf.getInt( CommonConfigurationKeys.HA_FC_ELECTOR_ZK_OP_RETRIES_KEY, CommonConfigurationKeys.HA_FC_ELECTOR_ZK_OP_RETRIES_DEFAULT); elector = new ActiveStandbyElector(zkQuorum, (int) zkSessionTimeout, electionZNode, zkAcls, zkAuths, this, maxRetryNum); elector.ensureParentZNode(); if (!isParentZnodeSafe(clusterId)) { notifyFatalError(electionZNode + " znode has invalid data! "+ "Might need formatting!"); } super.serviceInit(conf); }
ActiveStandbyElectorTester(String hostPort, int timeout, String parent, List<ACL> acl, ActiveStandbyElectorCallback app) throws IOException, KeeperException { super(hostPort, timeout, parent, acl, Collections .<ZKAuthInfo> emptyList(), app, CommonConfigurationKeys.HA_FC_ELECTOR_ZK_OP_RETRIES_DEFAULT); }
/** * Create the initial registry paths * @throws IOException any failure */ @VisibleForTesting public void createRootRegistryPaths() throws IOException { List<ACL> systemACLs = getRegistrySecurity().getSystemACLs(); LOG.info("System ACLs {}", RegistrySecurity.aclsToString(systemACLs)); maybeCreate("", CreateMode.PERSISTENT, systemACLs, false); maybeCreate(PATH_USERS, CreateMode.PERSISTENT, systemACLs, false); maybeCreate(PATH_SYSTEM_SERVICES, CreateMode.PERSISTENT, systemACLs, false); }
private Long convertACLsNTimes(ReferenceCountedACLCache cache, List<ACL> acl, int num) { if (num <= 0) { return -1L; } for (int i = 0; i < num -1; i++) { cache.convertAcls(acl); } return cache.convertAcls(acl); }
public ACLProvider aclProvider() { return new 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; } }; }
@Test public void testUGIProperties() throws Throwable { UserGroupInformation user = UserGroupInformation.getCurrentUser(); ACL acl = registrySecurity.createACLForUser(user, ZooDefs.Perms.ALL); assertFalse(RegistrySecurity.ALL_READWRITE_ACCESS.equals(acl)); LOG.info("User {} has ACL {}", user, acl); }
ChangeRecord(long zxid, String path, StatPersisted stat, int childCount, List<ACL> acl) { this.zxid = zxid; this.path = path; this.stat = stat; this.childCount = childCount; this.acl = acl; }
/** * createNodeWithACL * Create a node under ACL mode * @param path * @param payload * @throws Exception */ public void createNodeWithACL(String path, byte[] payload) throws Exception { ACL acl = new ACL(ZooDefs.Perms.ALL, ZooDefs.Ids.AUTH_IDS); List<ACL> aclList = Lists.newArrayList(acl); try { client.create().withACL(aclList).forPath(path, payload); } catch (Exception e) { logger.error("Create security file failed."); e.printStackTrace(); } }
@Test public void testCreateACL() throws ZooKeeperConnectionException, IOException { Configuration conf = HBaseConfiguration.create(); conf.set(Superusers.SUPERUSER_CONF_KEY, "user1,@group1,user2,@group2,user3"); String node = "/hbase/testCreateACL"; ZooKeeperWatcher watcher = new ZooKeeperWatcher(conf, node, null, false); List<ACL> aclList = ZKUtil.createACL(watcher, node, true); Assert.assertEquals(aclList.size(), 4); // 3+1, since ACL will be set for the creator by default Assert.assertTrue(!aclList.contains(new ACL(Perms.ALL, new Id("auth", "@group1"))) && !aclList.contains(new ACL(Perms.ALL, new Id("auth", "@group2")))); Assert.assertTrue(aclList.contains(new ACL(Perms.ALL, new Id("auth", "user1"))) && aclList.contains(new ACL(Perms.ALL, new Id("auth", "user2"))) && aclList.contains(new ACL(Perms.ALL, new Id("auth", "user3")))); }
@Override public void updateData(ZnodeModel model) throws DataModelSourceException { ZooKeeperConnection zooKeeperConnection = getZooKeeperConnection(); Znode znode = model.getData(); String path = model.getKey(); try { if (model.isDirtyAcl()) { List<ACL> acl = znode.getAcl(); zooKeeperConnection.setACL(path, acl, -1); model.setDirtyAcl(false); } if (model.isDirtyData()) { byte[] data = znode.getData(); zooKeeperConnection.setData(path, data, -1); model.setDirtyData(false); } } catch (Exception e) { throw new DataModelSourceException(e); } }
/** * When authentication is enabled on Zookeeper, /hbase/hbaseid should be * created with 2 ACLs: one specifies that the hbase user has full access * to the node; the other, that it is world-readable. */ @Test (timeout=30000) public void testHBaseIDZNodeACL() throws Exception { if (!secureZKAvailable) { return; } List<ACL> acls = zkw.getRecoverableZooKeeper().getZooKeeper() .getACL("/hbase/hbaseid", new Stat()); assertEquals(acls.size(),2); boolean foundWorldReadableAcl = false; boolean foundHBaseOwnerAcl = false; for(int i = 0; i < 2; i++) { if (acls.get(i).getId().getScheme().equals("world") == true) { assertEquals(acls.get(0).getId().getId(),"anyone"); assertEquals(acls.get(0).getPerms(), ZooDefs.Perms.READ); foundWorldReadableAcl = true; } else { if (acls.get(i).getId().getScheme().equals("sasl") == true) { assertEquals(acls.get(1).getId().getId(),"hbase"); assertEquals(acls.get(1).getId().getScheme(),"sasl"); foundHBaseOwnerAcl = true; } else { // error: should not get here: test fails. assertTrue(false); } } } assertTrue(foundWorldReadableAcl); assertTrue(foundHBaseOwnerAcl); }
/** * converts a long to a list of acls. * * @param longVal * @return a list of ACLs that map to the long */ public synchronized List<ACL> convertLong(Long longVal) { if (longVal == null) return null; if (longVal == OPEN_UNSAFE_ACL_ID) return ZooDefs.Ids.OPEN_ACL_UNSAFE; List<ACL> acls = longKeyMap.get(longVal); if (acls == null) { LOG.error("ERROR: ACL not available for long " + longVal); throw new RuntimeException("Failed to fetch acls for " + longVal); } return acls; }
private void addNewItem() { ACL acl = new ACL(); acl.setId(ZooDefs.Ids.ANYONE_ID_UNSAFE); acl.setPerms(ZooDefs.Perms.ALL); TableItem newItem = addAclTableItem(acl); Table table = getTable(); table.setSelection(newItem); tableSelectionChanged(newItem); fireOrchestrationChange(); }
private List<ACL> removeDuplicates(List<ACL> acl) { ArrayList<ACL> retval = new ArrayList<ACL>(); Iterator<ACL> it = acl.iterator(); while (it.hasNext()) { ACL a = it.next(); if (retval.contains(a) == false) { retval.add(a); } } return retval; }
/** * Parse the IDs, adding a realm if needed, setting the permissions * @param principalList id string * @param realm realm to add * @param perms permissions * @return the relevant ACLs * @throws IOException */ public List<ACL> buildACLs(String principalList, String realm, int perms) throws IOException { List<String> aclPairs = splitAclPairs(principalList, realm); List<ACL> ids = new ArrayList<ACL>(aclPairs.size()); for (String aclPair : aclPairs) { ACL newAcl = new ACL(); newAcl.setId(parse(aclPair, realm)); newAcl.setPerms(perms); ids.add(newAcl); } return ids; }
public DistributedQueue(ZooKeeper zookeeper, String dir, List<ACL> acl){ this.dir = dir; if(acl != null){ this.acl = acl; } this.zookeeper = zookeeper; }
/** * Recursively make a path * @param path path to create * @param acl ACL for path * @throws IOException any problem */ public void zkMkParentPath(String path, List<ACL> acl) throws IOException { // split path into elements zkMkPath(RegistryPathUtils.parentOf(path), CreateMode.PERSISTENT, true, acl); }
@Override public List<ACL> getACL(String path, Stat stat) throws KeeperException, InterruptedException { int count = 0; do { try { return super.getACL(path, stat); } catch (KeeperException.ConnectionLossException e) { LoggerFactory.getLogger().warn( "ZooKeeper connection lost. Trying to reconnect."); } } while (!closed && (limit == -1 || count++ < limit)); return null; }