diff --git a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/Credentials.java b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/Credentials.java index 29c706b958f..639a1e55485 100644 --- a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/Credentials.java +++ b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/Credentials.java @@ -17,6 +17,7 @@ */ package org.apache.hadoop.oncrpc.security; +import com.google.common.annotations.VisibleForTesting; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.oncrpc.XDR; @@ -66,4 +67,9 @@ public abstract class Credentials extends RpcAuthInfo { protected Credentials(AuthFlavor flavor) { super(flavor); } + + @VisibleForTesting + int getCredentialLength() { + return mCredentialsLength; + } } diff --git a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/CredentialsSys.java b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/CredentialsSys.java index d13c3615b2c..4d39de31703 100644 --- a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/CredentialsSys.java +++ b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/security/CredentialsSys.java @@ -20,6 +20,7 @@ package org.apache.hadoop.oncrpc.security; import java.net.InetAddress; import java.net.UnknownHostException; +import com.google.common.annotations.VisibleForTesting; import org.apache.commons.io.Charsets; import org.apache.hadoop.oncrpc.XDR; @@ -63,6 +64,11 @@ public class CredentialsSys extends Credentials { return mAuxGIDs; } + @VisibleForTesting + int getStamp() { + return mStamp; + } + public void setGID(int gid) { this.mGID = gid; } @@ -75,6 +81,11 @@ public class CredentialsSys extends Credentials { this.mStamp = stamp; } + @VisibleForTesting + void setHostName(String hostname) { + this.mHostName = hostname; + } + @Override public void read(XDR xdr) { mCredentialsLength = xdr.readInt(); @@ -93,8 +104,14 @@ public class CredentialsSys extends Credentials { @Override public void write(XDR xdr) { + int padding = 0; + // Ensure there are padding bytes if hostname is not a multiple of 4. + padding = 4 - (mHostName.getBytes(Charsets.UTF_8).length % 4); + // padding bytes is zero if hostname is already a multiple of 4. + padding = padding % 4; // mStamp + mHostName.length + mHostName + mUID + mGID + mAuxGIDs.count mCredentialsLength = 20 + mHostName.getBytes(Charsets.UTF_8).length; + mCredentialsLength = mCredentialsLength + padding; // mAuxGIDs if (mAuxGIDs != null && mAuxGIDs.length > 0) { mCredentialsLength += mAuxGIDs.length * 4; diff --git a/hadoop-common-project/hadoop-nfs/src/test/java/org/apache/hadoop/oncrpc/security/TestCredentialsSys.java b/hadoop-common-project/hadoop-nfs/src/test/java/org/apache/hadoop/oncrpc/security/TestCredentialsSys.java index 2b9e339d6ea..745ac5cdfd1 100644 --- a/hadoop-common-project/hadoop-nfs/src/test/java/org/apache/hadoop/oncrpc/security/TestCredentialsSys.java +++ b/hadoop-common-project/hadoop-nfs/src/test/java/org/apache/hadoop/oncrpc/security/TestCredentialsSys.java @@ -33,6 +33,7 @@ public class TestCredentialsSys { CredentialsSys credential = new CredentialsSys(); credential.setUID(0); credential.setGID(1); + credential.setStamp(1234); XDR xdr = new XDR(); credential.write(xdr); @@ -42,5 +43,46 @@ public class TestCredentialsSys { assertEquals(0, newCredential.getUID()); assertEquals(1, newCredential.getGID()); + assertEquals(1234, newCredential.getStamp()); + } + + @Test + public void testHostNameNotMultipleOf4() { + CredentialsSys credential = new CredentialsSys(); + credential.setUID(0); + credential.setGID(1); + credential.setStamp(1234); + credential.setHostName("hadoop-nfs"); + + XDR xdr = new XDR(); + credential.write(xdr); + + CredentialsSys newCredential = new CredentialsSys(); + newCredential.read(xdr.asReadOnlyWrap()); + + assertEquals(0, newCredential.getUID()); + assertEquals(1, newCredential.getGID()); + assertEquals(1234, newCredential.getStamp()); + assertEquals(32, newCredential.getCredentialLength()); + } + + @Test + public void testHostNameMultipleOf4() { + CredentialsSys credential = new CredentialsSys(); + credential.setUID(0); + credential.setGID(1); + credential.setStamp(1234); + credential.setHostName("apachehadoop"); + + XDR xdr = new XDR(); + credential.write(xdr); + + CredentialsSys newCredential = new CredentialsSys(); + newCredential.read(xdr.asReadOnlyWrap()); + + assertEquals(0, newCredential.getUID()); + assertEquals(1, newCredential.getGID()); + assertEquals(1234, newCredential.getStamp()); + assertEquals(32, newCredential.getCredentialLength()); } }