/** * Set the FileEncryptionInfo for an INode. */ void setFileEncryptionInfo(String src, FileEncryptionInfo info) throws IOException { // Make the PB for the xattr final HdfsProtos.PerFileEncryptionInfoProto proto = PBHelper.convertPerFileEncInfo(info); final byte[] protoBytes = proto.toByteArray(); final XAttr fileEncryptionAttr = XAttrHelper.buildXAttr(CRYPTO_XATTR_FILE_ENCRYPTION_INFO, protoBytes); final List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1); xAttrs.add(fileEncryptionAttr); writeLock(); try { FSDirXAttrOp.unprotectedSetXAttrs(this, src, xAttrs, EnumSet.of(XAttrSetFlag.CREATE)); } finally { writeUnlock(); } }
static void checkPermissionForApi(FSPermissionChecker pc, XAttr xAttr, boolean isRawPath) throws AccessControlException { final boolean isSuperUser = pc.isSuperUser(); if (xAttr.getNameSpace() == XAttr.NameSpace.USER || (xAttr.getNameSpace() == XAttr.NameSpace.TRUSTED && isSuperUser)) { return; } if (xAttr.getNameSpace() == XAttr.NameSpace.RAW && isRawPath && isSuperUser) { return; } if (XAttrHelper.getPrefixName(xAttr). equals(SECURITY_XATTR_UNREADABLE_BY_SUPERUSER)) { if (xAttr.getValue() != null) { throw new AccessControlException("Attempt to set a value for '" + SECURITY_XATTR_UNREADABLE_BY_SUPERUSER + "'. Values are not allowed for this xattr."); } return; } throw new AccessControlException("User doesn't have permission for xattr: " + XAttrHelper.getPrefixName(xAttr)); }
@Test public void testToXAttrMap() throws IOException { String jsonString = "{\"XAttrs\":[{\"name\":\"user.a1\",\"value\":\"0x313233\"}," + "{\"name\":\"user.a2\",\"value\":\"0x313131\"}]}"; ObjectReader reader = new ObjectMapper().reader(Map.class); Map<?, ?> json = reader.readValue(jsonString); XAttr xAttr1 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a1").setValue(XAttrCodec.decodeValue("0x313233")).build(); XAttr xAttr2 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a2").setValue(XAttrCodec.decodeValue("0x313131")).build(); List<XAttr> xAttrs = Lists.newArrayList(); xAttrs.add(xAttr1); xAttrs.add(xAttr2); Map<String, byte[]> xAttrMap = XAttrHelper.buildXAttrMap(xAttrs); Map<String, byte[]> parsedXAttrMap = JsonUtil.toXAttrs(json); Assert.assertEquals(xAttrMap.size(), parsedXAttrMap.size()); Iterator<Entry<String, byte[]>> iter = xAttrMap.entrySet().iterator(); while(iter.hasNext()) { Entry<String, byte[]> entry = iter.next(); Assert.assertArrayEquals(entry.getValue(), parsedXAttrMap.get(entry.getKey())); } }
/** * Set the FileEncryptionInfo for an INode. * * @param fsd fsdirectory * @param src the path of a directory which will be the root of the * encryption zone. * @param info file encryption information * @throws IOException */ static void setFileEncryptionInfo(final FSDirectory fsd, final String src, final FileEncryptionInfo info) throws IOException { // Make the PB for the xattr final HdfsProtos.PerFileEncryptionInfoProto proto = PBHelperClient.convertPerFileEncInfo(info); final byte[] protoBytes = proto.toByteArray(); final XAttr fileEncryptionAttr = XAttrHelper.buildXAttr(CRYPTO_XATTR_FILE_ENCRYPTION_INFO, protoBytes); final List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1); xAttrs.add(fileEncryptionAttr); fsd.writeLock(); try { FSDirXAttrOp.unprotectedSetXAttrs(fsd, src, xAttrs, EnumSet.of(XAttrSetFlag.CREATE)); } finally { fsd.writeUnlock(); } }
static void checkPermissionForApi(FSPermissionChecker pc, XAttr xAttr, boolean isRawPath) throws AccessControlException { final boolean isSuperUser = pc.isSuperUser(); if (xAttr.getNameSpace() == XAttr.NameSpace.USER || (xAttr.getNameSpace() == XAttr.NameSpace.TRUSTED && isSuperUser)) { return; } if (xAttr.getNameSpace() == XAttr.NameSpace.RAW && isRawPath && isSuperUser) { return; } if (XAttrHelper.getPrefixedName(xAttr). equals(SECURITY_XATTR_UNREADABLE_BY_SUPERUSER)) { if (xAttr.getValue() != null) { throw new AccessControlException("Attempt to set a value for '" + SECURITY_XATTR_UNREADABLE_BY_SUPERUSER + "'. Values are not allowed for this xattr."); } return; } throw new AccessControlException("User doesn't have permission for xattr: " + XAttrHelper.getPrefixedName(xAttr)); }
@Test public void testToXAttrMap() throws IOException { String jsonString = "{\"XAttrs\":[{\"name\":\"user.a1\",\"value\":\"0x313233\"}," + "{\"name\":\"user.a2\",\"value\":\"0x313131\"}]}"; ObjectReader reader = new ObjectMapper().reader(Map.class); Map<?, ?> json = reader.readValue(jsonString); XAttr xAttr1 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a1").setValue(XAttrCodec.decodeValue("0x313233")).build(); XAttr xAttr2 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a2").setValue(XAttrCodec.decodeValue("0x313131")).build(); List<XAttr> xAttrs = Lists.newArrayList(); xAttrs.add(xAttr1); xAttrs.add(xAttr2); Map<String, byte[]> xAttrMap = XAttrHelper.buildXAttrMap(xAttrs); Map<String, byte[]> parsedXAttrMap = JsonUtilClient.toXAttrs(json); Assert.assertEquals(xAttrMap.size(), parsedXAttrMap.size()); Iterator<Entry<String, byte[]>> iter = xAttrMap.entrySet().iterator(); while(iter.hasNext()) { Entry<String, byte[]> entry = iter.next(); Assert.assertArrayEquals(entry.getValue(), parsedXAttrMap.get(entry.getKey())); } }
/** * Set the FileEncryptionInfo for an INode. */ void setFileEncryptionInfo(String src, FileEncryptionInfo info) throws IOException { // Make the PB for the xattr final HdfsProtos.PerFileEncryptionInfoProto proto = PBHelper.convertPerFileEncInfo(info); final byte[] protoBytes = proto.toByteArray(); final XAttr fileEncryptionAttr = XAttrHelper.buildXAttr(CRYPTO_XATTR_FILE_ENCRYPTION_INFO, protoBytes); final List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1); xAttrs.add(fileEncryptionAttr); writeLock(); try { unprotectedSetXAttrs(src, xAttrs, EnumSet.of(XAttrSetFlag.CREATE)); } finally { writeUnlock(); } }
@Test public void testToXAttrMap() throws IOException { String jsonString = "{\"XAttrs\":[{\"name\":\"user.a1\",\"value\":\"0x313233\"}," + "{\"name\":\"user.a2\",\"value\":\"0x313131\"}]}"; Map<?, ?> json = (Map<?, ?>)JSON.parse(jsonString); XAttr xAttr1 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a1").setValue(XAttrCodec.decodeValue("0x313233")).build(); XAttr xAttr2 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a2").setValue(XAttrCodec.decodeValue("0x313131")).build(); List<XAttr> xAttrs = Lists.newArrayList(); xAttrs.add(xAttr1); xAttrs.add(xAttr2); Map<String, byte[]> xAttrMap = XAttrHelper.buildXAttrMap(xAttrs); Map<String, byte[]> parsedXAttrMap = JsonUtil.toXAttrs(json); Assert.assertEquals(xAttrMap.size(), parsedXAttrMap.size()); Iterator<Entry<String, byte[]>> iter = xAttrMap.entrySet().iterator(); while(iter.hasNext()) { Entry<String, byte[]> entry = iter.next(); Assert.assertArrayEquals(entry.getValue(), parsedXAttrMap.get(entry.getKey())); } }
private static Map<String, Object> toJsonMap(final XAttr xAttr, final XAttrCodec encoding) throws IOException { if (xAttr == null) { return null; } final Map<String, Object> m = new TreeMap<String, Object>(); m.put("name", XAttrHelper.getPrefixName(xAttr)); m.put("value", xAttr.getValue() != null ? XAttrCodec.encodeValue(xAttr.getValue(), encoding) : null); return m; }
public static String toJsonString(final List<XAttr> xAttrs) throws IOException { final List<String> names = Lists.newArrayListWithCapacity(xAttrs.size()); for (XAttr xAttr : xAttrs) { names.add(XAttrHelper.getPrefixName(xAttr)); } ObjectMapper mapper = new ObjectMapper(); String ret = mapper.writeValueAsString(names); final Map<String, Object> finalMap = new TreeMap<String, Object>(); finalMap.put("XAttrNames", ret); return mapper.writeValueAsString(finalMap); }
/** * This method is always called with writeLock of FSDirectory held. */ public final void addToInodeMap(INode inode) { if (inode instanceof INodeWithAdditionalFields) { inodeMap.put(inode); if (!inode.isSymlink()) { final XAttrFeature xaf = inode.getXAttrFeature(); if (xaf != null) { final List<XAttr> xattrs = xaf.getXAttrs(); for (XAttr xattr : xattrs) { final String xaName = XAttrHelper.getPrefixName(xattr); if (CRYPTO_XATTR_ENCRYPTION_ZONE.equals(xaName)) { try { final HdfsProtos.ZoneEncryptionInfoProto ezProto = HdfsProtos.ZoneEncryptionInfoProto.parseFrom( xattr.getValue()); ezManager.unprotectedAddEncryptionZone(inode.getId(), PBHelper.convert(ezProto.getSuite()), PBHelper.convert(ezProto.getCryptoProtocolVersion()), ezProto.getKeyName()); } catch (InvalidProtocolBufferException e) { NameNode.LOG.warn("Error parsing protocol buffer of " + "EZ XAttr " + xattr.getName()); } } } } } } }
private void checkUnreadableBySuperuser(FSPermissionChecker pc, INode inode, int snapshotId) throws IOException { if (pc.isSuperUser()) { for (XAttr xattr : FSDirXAttrOp.getXAttrs(dir, inode, snapshotId)) { if (XAttrHelper.getPrefixName(xattr). equals(SECURITY_XATTR_UNREADABLE_BY_SUPERUSER)) { throw new AccessControlException("Access is denied for " + pc.getUser() + " since the superuser is not allowed to " + "perform this operation."); } } } }
static XAttr unprotectedGetXAttrByName( INode inode, int snapshotId, String xAttrName) throws IOException { List<XAttr> xAttrs = XAttrStorage.readINodeXAttrs(inode, snapshotId); if (xAttrs == null) { return null; } for (XAttr x : xAttrs) { if (XAttrHelper.getPrefixName(x) .equals(xAttrName)) { return x; } } return null; }
/** * Return the JSON formatted XAttrs of the specified file. * * @param path * a path specifies a file * @return JSON formatted XAttrs * @throws IOException * if failed to serialize fileStatus to JSON. */ String getXAttrs(String path, List<String> names, String encoder) throws IOException { List<XAttr> xAttrs = getXAttrList(path); List<XAttr> filtered; if (names == null || names.size() == 0) { filtered = xAttrs; } else { filtered = Lists.newArrayListWithCapacity(names.size()); for (String name : names) { XAttr search = XAttrHelper.buildXAttr(name); boolean found = false; for (XAttr aXAttr : xAttrs) { if (aXAttr.getNameSpace() == search.getNameSpace() && aXAttr.getName().equals(search.getName())) { filtered.add(aXAttr); found = true; break; } } if (!found) { throw new IOException( "At least one of the attributes provided was not found."); } } } return JsonUtil.toJsonString(filtered, new XAttrEncodingParam(encoder).getEncoding()); }
private static Map<String, Object> toJsonMap(final XAttr xAttr, final XAttrCodec encoding) throws IOException { if (xAttr == null) { return null; } final Map<String, Object> m = new TreeMap<String, Object>(); m.put("name", XAttrHelper.getPrefixedName(xAttr)); m.put("value", xAttr.getValue() != null ? XAttrCodec.encodeValue(xAttr.getValue(), encoding) : null); return m; }
public static String toJsonString(final List<XAttr> xAttrs) throws IOException { final List<String> names = Lists.newArrayListWithCapacity(xAttrs.size()); for (XAttr xAttr : xAttrs) { names.add(XAttrHelper.getPrefixedName(xAttr)); } ObjectMapper mapper = new ObjectMapper(); String ret = mapper.writeValueAsString(names); final Map<String, Object> finalMap = new TreeMap<String, Object>(); finalMap.put("XAttrNames", ret); return mapper.writeValueAsString(finalMap); }
/** * Get XAttr by name with prefix. * @param prefixedName xAttr name with prefix * @return the XAttr */ public XAttr getXAttr(String prefixedName) { XAttr attr = XAttrFormat.getXAttr(attrs, prefixedName); if (attr == null && xAttrs != null) { XAttr toFind = XAttrHelper.buildXAttr(prefixedName); for (XAttr a : xAttrs) { if (a.equalsIgnoreValue(toFind)) { attr = a; break; } } } return attr; }
/** * Get XAttr by name with prefix. * Will unpack the byte[] until find the specific XAttr * * @param attrs the packed bytes of XAttrs * @param prefixedName the XAttr name with prefix * @return the XAttr */ static XAttr getXAttr(byte[] attrs, String prefixedName) { if (prefixedName == null || attrs == null) { return null; } XAttr xAttr = XAttrHelper.buildXAttr(prefixedName); for (int i = 0; i < attrs.length;) { // big-endian int v = Ints.fromBytes(attrs[i], attrs[i + 1], attrs[i + 2], attrs[i + 3]); i += 4; int ns = (v >> XATTR_NAMESPACE_OFFSET) & XATTR_NAMESPACE_MASK; int nid = v & XATTR_NAME_MASK; XAttr.NameSpace namespace = XATTR_NAMESPACE_VALUES[ns]; String name = XAttrStorage.getName(nid); int vlen = ((0xff & attrs[i]) << 8) | (0xff & attrs[i + 1]); i += 2; if (xAttr.getNameSpace() == namespace && xAttr.getName().equals(name)) { if (vlen > 0) { byte[] value = new byte[vlen]; System.arraycopy(attrs, i, value, 0, vlen); return new XAttr.Builder().setNameSpace(namespace). setName(name).setValue(value).build(); } return xAttr; } i += vlen; } return null; }
/** * Create a populated namespace for later testing. Save its contents to a data * structure and store its fsimage location. We only want to generate the * fsimage file once and use it for multiple tests. */ @BeforeClass public static void createOriginalFSImage() throws IOException { MiniDFSCluster cluster = null; Configuration conf = new Configuration(); try { cluster = new MiniDFSCluster.Builder(conf).build(); cluster.waitActive(); DistributedFileSystem hdfs = cluster.getFileSystem(); // Create a name space with XAttributes Path dir = new Path("/dir1"); hdfs.mkdirs(dir); hdfs.setXAttr(dir, "user.attr1", "value1".getBytes()); hdfs.setXAttr(dir, "user.attr2", "value2".getBytes()); // Write results to the fsimage file hdfs.setSafeMode(HdfsConstants.SafeModeAction.SAFEMODE_ENTER, false); hdfs.saveNamespace(); List<XAttr> attributes = new ArrayList<XAttr>(); attributes.add(XAttrHelper.buildXAttr("user.attr1", "value1".getBytes())); attr1JSon = JsonUtil.toJsonString(attributes, null); attributes.add(XAttrHelper.buildXAttr("user.attr2", "value2".getBytes())); // Determine the location of the fsimage file originalFsimage = FSImageTestUtil.findLatestImageFile(FSImageTestUtil .getFSImage(cluster.getNameNode()).getStorage().getStorageDir(0)); if (originalFsimage == null) { throw new RuntimeException("Didn't generate or can't find fsimage"); } LOG.debug("original FS image file is " + originalFsimage); } finally { if (cluster != null) cluster.shutdown(); } }
public static String toJsonString(final List<XAttr> xAttrs) throws IOException { final List<String> names = Lists.newArrayListWithCapacity(xAttrs.size()); for (XAttr xAttr : xAttrs) { names.add(XAttrHelper.getPrefixName(xAttr)); } String ret = JSON.toString(names); final Map<String, Object> finalMap = new TreeMap<String, Object>(); finalMap.put("XAttrNames", ret); return JSON.toString(finalMap); }
private XAttr unprotectedGetXAttrByName(INode inode, int snapshotId, String xAttrName) throws IOException { List<XAttr> xAttrs = XAttrStorage.readINodeXAttrs(inode, snapshotId); if (xAttrs == null) { return null; } for (XAttr x : xAttrs) { if (XAttrHelper.getPrefixName(x) .equals(xAttrName)) { return x; } } return null; }
private void checkUnreadableBySuperuser(FSPermissionChecker pc, INode inode, int snapshotId) throws IOException { if (pc.isSuperUser()) { for (XAttr xattr : dir.getXAttrs(inode, snapshotId)) { if (XAttrHelper.getPrefixName(xattr). equals(SECURITY_XATTR_UNREADABLE_BY_SUPERUSER)) { throw new AccessControlException("Access is denied for " + pc.getUser() + " since the superuser is not allowed to " + "perform this operation."); } } } }