You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by el...@apache.org on 2015/02/13 20:33:30 UTC

[6/7] accumulo git commit: ACCUMULO-3513 Add delegation token support for kerberos configurations

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java b/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java
index 4b90a34..9cd1084 100644
--- a/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java
+++ b/core/src/main/java/org/apache/accumulo/core/master/thrift/MasterClientService.java
@@ -84,6 +84,8 @@ import org.slf4j.LoggerFactory;
 
     public List<String> getActiveTservers(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException;
 
+    public org.apache.accumulo.core.security.thrift.TDelegationToken getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException;
+
   }
 
   public interface AsyncIface extends FateService .AsyncIface {
@@ -120,6 +122,8 @@ import org.slf4j.LoggerFactory;
 
     public void getActiveTservers(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
 
+    public void getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
   }
 
   public static class Client extends FateService.Client implements Iface {
@@ -555,6 +559,34 @@ import org.slf4j.LoggerFactory;
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getActiveTservers failed: unknown result");
     }
 
+    public org.apache.accumulo.core.security.thrift.TDelegationToken getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException
+    {
+      send_getDelegationToken(tinfo, credentials, cfg);
+      return recv_getDelegationToken();
+    }
+
+    public void send_getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) throws org.apache.thrift.TException
+    {
+      getDelegationToken_args args = new getDelegationToken_args();
+      args.setTinfo(tinfo);
+      args.setCredentials(credentials);
+      args.setCfg(cfg);
+      sendBase("getDelegationToken", args);
+    }
+
+    public org.apache.accumulo.core.security.thrift.TDelegationToken recv_getDelegationToken() throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException
+    {
+      getDelegationToken_result result = new getDelegationToken_result();
+      receiveBase(result, "getDelegationToken");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.sec != null) {
+        throw result.sec;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getDelegationToken failed: unknown result");
+    }
+
   }
   public static class AsyncClient extends FateService.AsyncClient implements AsyncIface {
     public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
@@ -1212,6 +1244,44 @@ import org.slf4j.LoggerFactory;
       }
     }
 
+    public void getDelegationToken(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      getDelegationToken_call method_call = new getDelegationToken_call(tinfo, credentials, cfg, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class getDelegationToken_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private org.apache.accumulo.core.trace.thrift.TInfo tinfo;
+      private org.apache.accumulo.core.security.thrift.TCredentials credentials;
+      private org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg;
+      public getDelegationToken_call(org.apache.accumulo.core.trace.thrift.TInfo tinfo, org.apache.accumulo.core.security.thrift.TCredentials credentials, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.tinfo = tinfo;
+        this.credentials = credentials;
+        this.cfg = cfg;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getDelegationToken", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        getDelegationToken_args args = new getDelegationToken_args();
+        args.setTinfo(tinfo);
+        args.setCredentials(credentials);
+        args.setCfg(cfg);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public org.apache.accumulo.core.security.thrift.TDelegationToken getResult() throws org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_getDelegationToken();
+      }
+    }
+
   }
 
   public static class Processor<I extends Iface> extends FateService.Processor<I> implements org.apache.thrift.TProcessor {
@@ -1241,6 +1311,7 @@ import org.slf4j.LoggerFactory;
       processMap.put("reportSplitExtent", new reportSplitExtent());
       processMap.put("reportTabletStatus", new reportTabletStatus());
       processMap.put("getActiveTservers", new getActiveTservers());
+      processMap.put("getDelegationToken", new getDelegationToken());
       return processMap;
     }
 
@@ -1627,6 +1698,30 @@ import org.slf4j.LoggerFactory;
       }
     }
 
+    public static class getDelegationToken<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getDelegationToken_args> {
+      public getDelegationToken() {
+        super("getDelegationToken");
+      }
+
+      public getDelegationToken_args getEmptyArgsInstance() {
+        return new getDelegationToken_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public getDelegationToken_result getResult(I iface, getDelegationToken_args args) throws org.apache.thrift.TException {
+        getDelegationToken_result result = new getDelegationToken_result();
+        try {
+          result.success = iface.getDelegationToken(args.tinfo, args.credentials, args.cfg);
+        } catch (org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec) {
+          result.sec = sec;
+        }
+        return result;
+      }
+    }
+
   }
 
   public static class AsyncProcessor<I extends AsyncIface> extends FateService.AsyncProcessor<I> {
@@ -1656,6 +1751,7 @@ import org.slf4j.LoggerFactory;
       processMap.put("reportSplitExtent", new reportSplitExtent());
       processMap.put("reportTabletStatus", new reportTabletStatus());
       processMap.put("getActiveTservers", new getActiveTservers());
+      processMap.put("getDelegationToken", new getDelegationToken());
       return processMap;
     }
 
@@ -2527,6 +2623,63 @@ import org.slf4j.LoggerFactory;
       }
     }
 
+    public static class getDelegationToken<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getDelegationToken_args, org.apache.accumulo.core.security.thrift.TDelegationToken> {
+      public getDelegationToken() {
+        super("getDelegationToken");
+      }
+
+      public getDelegationToken_args getEmptyArgsInstance() {
+        return new getDelegationToken_args();
+      }
+
+      public AsyncMethodCallback<org.apache.accumulo.core.security.thrift.TDelegationToken> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<org.apache.accumulo.core.security.thrift.TDelegationToken>() { 
+          public void onComplete(org.apache.accumulo.core.security.thrift.TDelegationToken o) {
+            getDelegationToken_result result = new getDelegationToken_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            getDelegationToken_result result = new getDelegationToken_result();
+            if (e instanceof org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException) {
+                        result.sec = (org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException) e;
+                        result.setSecIsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, getDelegationToken_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.accumulo.core.security.thrift.TDelegationToken> resultHandler) throws TException {
+        iface.getDelegationToken(args.tinfo, args.credentials, args.cfg,resultHandler);
+      }
+    }
+
   }
 
   public static class initiateFlush_args implements org.apache.thrift.TBase<initiateFlush_args, initiateFlush_args._Fields>, java.io.Serializable, Cloneable, Comparable<initiateFlush_args>   {
@@ -18540,4 +18693,1034 @@ import org.slf4j.LoggerFactory;
 
   }
 
+  public static class getDelegationToken_args implements org.apache.thrift.TBase<getDelegationToken_args, getDelegationToken_args._Fields>, java.io.Serializable, Cloneable, Comparable<getDelegationToken_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDelegationToken_args");
+
+    private static final org.apache.thrift.protocol.TField TINFO_FIELD_DESC = new org.apache.thrift.protocol.TField("tinfo", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField CREDENTIALS_FIELD_DESC = new org.apache.thrift.protocol.TField("credentials", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField CFG_FIELD_DESC = new org.apache.thrift.protocol.TField("cfg", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new getDelegationToken_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new getDelegationToken_argsTupleSchemeFactory());
+    }
+
+    public org.apache.accumulo.core.trace.thrift.TInfo tinfo; // required
+    public org.apache.accumulo.core.security.thrift.TCredentials credentials; // required
+    public org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      TINFO((short)1, "tinfo"),
+      CREDENTIALS((short)2, "credentials"),
+      CFG((short)3, "cfg");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // TINFO
+            return TINFO;
+          case 2: // CREDENTIALS
+            return CREDENTIALS;
+          case 3: // CFG
+            return CFG;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.TINFO, new org.apache.thrift.meta_data.FieldMetaData("tinfo", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.trace.thrift.TInfo.class)));
+      tmpMap.put(_Fields.CREDENTIALS, new org.apache.thrift.meta_data.FieldMetaData("credentials", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.security.thrift.TCredentials.class)));
+      tmpMap.put(_Fields.CFG, new org.apache.thrift.meta_data.FieldMetaData("cfg", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.security.thrift.TDelegationTokenConfig.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDelegationToken_args.class, metaDataMap);
+    }
+
+    public getDelegationToken_args() {
+    }
+
+    public getDelegationToken_args(
+      org.apache.accumulo.core.trace.thrift.TInfo tinfo,
+      org.apache.accumulo.core.security.thrift.TCredentials credentials,
+      org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg)
+    {
+      this();
+      this.tinfo = tinfo;
+      this.credentials = credentials;
+      this.cfg = cfg;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getDelegationToken_args(getDelegationToken_args other) {
+      if (other.isSetTinfo()) {
+        this.tinfo = new org.apache.accumulo.core.trace.thrift.TInfo(other.tinfo);
+      }
+      if (other.isSetCredentials()) {
+        this.credentials = new org.apache.accumulo.core.security.thrift.TCredentials(other.credentials);
+      }
+      if (other.isSetCfg()) {
+        this.cfg = new org.apache.accumulo.core.security.thrift.TDelegationTokenConfig(other.cfg);
+      }
+    }
+
+    public getDelegationToken_args deepCopy() {
+      return new getDelegationToken_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.tinfo = null;
+      this.credentials = null;
+      this.cfg = null;
+    }
+
+    public org.apache.accumulo.core.trace.thrift.TInfo getTinfo() {
+      return this.tinfo;
+    }
+
+    public getDelegationToken_args setTinfo(org.apache.accumulo.core.trace.thrift.TInfo tinfo) {
+      this.tinfo = tinfo;
+      return this;
+    }
+
+    public void unsetTinfo() {
+      this.tinfo = null;
+    }
+
+    /** Returns true if field tinfo is set (has been assigned a value) and false otherwise */
+    public boolean isSetTinfo() {
+      return this.tinfo != null;
+    }
+
+    public void setTinfoIsSet(boolean value) {
+      if (!value) {
+        this.tinfo = null;
+      }
+    }
+
+    public org.apache.accumulo.core.security.thrift.TCredentials getCredentials() {
+      return this.credentials;
+    }
+
+    public getDelegationToken_args setCredentials(org.apache.accumulo.core.security.thrift.TCredentials credentials) {
+      this.credentials = credentials;
+      return this;
+    }
+
+    public void unsetCredentials() {
+      this.credentials = null;
+    }
+
+    /** Returns true if field credentials is set (has been assigned a value) and false otherwise */
+    public boolean isSetCredentials() {
+      return this.credentials != null;
+    }
+
+    public void setCredentialsIsSet(boolean value) {
+      if (!value) {
+        this.credentials = null;
+      }
+    }
+
+    public org.apache.accumulo.core.security.thrift.TDelegationTokenConfig getCfg() {
+      return this.cfg;
+    }
+
+    public getDelegationToken_args setCfg(org.apache.accumulo.core.security.thrift.TDelegationTokenConfig cfg) {
+      this.cfg = cfg;
+      return this;
+    }
+
+    public void unsetCfg() {
+      this.cfg = null;
+    }
+
+    /** Returns true if field cfg is set (has been assigned a value) and false otherwise */
+    public boolean isSetCfg() {
+      return this.cfg != null;
+    }
+
+    public void setCfgIsSet(boolean value) {
+      if (!value) {
+        this.cfg = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case TINFO:
+        if (value == null) {
+          unsetTinfo();
+        } else {
+          setTinfo((org.apache.accumulo.core.trace.thrift.TInfo)value);
+        }
+        break;
+
+      case CREDENTIALS:
+        if (value == null) {
+          unsetCredentials();
+        } else {
+          setCredentials((org.apache.accumulo.core.security.thrift.TCredentials)value);
+        }
+        break;
+
+      case CFG:
+        if (value == null) {
+          unsetCfg();
+        } else {
+          setCfg((org.apache.accumulo.core.security.thrift.TDelegationTokenConfig)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case TINFO:
+        return getTinfo();
+
+      case CREDENTIALS:
+        return getCredentials();
+
+      case CFG:
+        return getCfg();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case TINFO:
+        return isSetTinfo();
+      case CREDENTIALS:
+        return isSetCredentials();
+      case CFG:
+        return isSetCfg();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getDelegationToken_args)
+        return this.equals((getDelegationToken_args)that);
+      return false;
+    }
+
+    public boolean equals(getDelegationToken_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_tinfo = true && this.isSetTinfo();
+      boolean that_present_tinfo = true && that.isSetTinfo();
+      if (this_present_tinfo || that_present_tinfo) {
+        if (!(this_present_tinfo && that_present_tinfo))
+          return false;
+        if (!this.tinfo.equals(that.tinfo))
+          return false;
+      }
+
+      boolean this_present_credentials = true && this.isSetCredentials();
+      boolean that_present_credentials = true && that.isSetCredentials();
+      if (this_present_credentials || that_present_credentials) {
+        if (!(this_present_credentials && that_present_credentials))
+          return false;
+        if (!this.credentials.equals(that.credentials))
+          return false;
+      }
+
+      boolean this_present_cfg = true && this.isSetCfg();
+      boolean that_present_cfg = true && that.isSetCfg();
+      if (this_present_cfg || that_present_cfg) {
+        if (!(this_present_cfg && that_present_cfg))
+          return false;
+        if (!this.cfg.equals(that.cfg))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    @Override
+    public int compareTo(getDelegationToken_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetTinfo()).compareTo(other.isSetTinfo());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetTinfo()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tinfo, other.tinfo);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetCredentials()).compareTo(other.isSetCredentials());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetCredentials()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.credentials, other.credentials);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetCfg()).compareTo(other.isSetCfg());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetCfg()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cfg, other.cfg);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getDelegationToken_args(");
+      boolean first = true;
+
+      sb.append("tinfo:");
+      if (this.tinfo == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.tinfo);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("credentials:");
+      if (this.credentials == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.credentials);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("cfg:");
+      if (this.cfg == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.cfg);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (tinfo != null) {
+        tinfo.validate();
+      }
+      if (credentials != null) {
+        credentials.validate();
+      }
+      if (cfg != null) {
+        cfg.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getDelegationToken_argsStandardSchemeFactory implements SchemeFactory {
+      public getDelegationToken_argsStandardScheme getScheme() {
+        return new getDelegationToken_argsStandardScheme();
+      }
+    }
+
+    private static class getDelegationToken_argsStandardScheme extends StandardScheme<getDelegationToken_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, getDelegationToken_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // TINFO
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.tinfo = new org.apache.accumulo.core.trace.thrift.TInfo();
+                struct.tinfo.read(iprot);
+                struct.setTinfoIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // CREDENTIALS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.credentials = new org.apache.accumulo.core.security.thrift.TCredentials();
+                struct.credentials.read(iprot);
+                struct.setCredentialsIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // CFG
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.cfg = new org.apache.accumulo.core.security.thrift.TDelegationTokenConfig();
+                struct.cfg.read(iprot);
+                struct.setCfgIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, getDelegationToken_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.tinfo != null) {
+          oprot.writeFieldBegin(TINFO_FIELD_DESC);
+          struct.tinfo.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.credentials != null) {
+          oprot.writeFieldBegin(CREDENTIALS_FIELD_DESC);
+          struct.credentials.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.cfg != null) {
+          oprot.writeFieldBegin(CFG_FIELD_DESC);
+          struct.cfg.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getDelegationToken_argsTupleSchemeFactory implements SchemeFactory {
+      public getDelegationToken_argsTupleScheme getScheme() {
+        return new getDelegationToken_argsTupleScheme();
+      }
+    }
+
+    private static class getDelegationToken_argsTupleScheme extends TupleScheme<getDelegationToken_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetTinfo()) {
+          optionals.set(0);
+        }
+        if (struct.isSetCredentials()) {
+          optionals.set(1);
+        }
+        if (struct.isSetCfg()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetTinfo()) {
+          struct.tinfo.write(oprot);
+        }
+        if (struct.isSetCredentials()) {
+          struct.credentials.write(oprot);
+        }
+        if (struct.isSetCfg()) {
+          struct.cfg.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.tinfo = new org.apache.accumulo.core.trace.thrift.TInfo();
+          struct.tinfo.read(iprot);
+          struct.setTinfoIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.credentials = new org.apache.accumulo.core.security.thrift.TCredentials();
+          struct.credentials.read(iprot);
+          struct.setCredentialsIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.cfg = new org.apache.accumulo.core.security.thrift.TDelegationTokenConfig();
+          struct.cfg.read(iprot);
+          struct.setCfgIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class getDelegationToken_result implements org.apache.thrift.TBase<getDelegationToken_result, getDelegationToken_result._Fields>, java.io.Serializable, Cloneable, Comparable<getDelegationToken_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDelegationToken_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
+    private static final org.apache.thrift.protocol.TField SEC_FIELD_DESC = new org.apache.thrift.protocol.TField("sec", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new getDelegationToken_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new getDelegationToken_resultTupleSchemeFactory());
+    }
+
+    public org.apache.accumulo.core.security.thrift.TDelegationToken success; // required
+    public org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      SEC((short)1, "sec");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // SEC
+            return SEC;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.accumulo.core.security.thrift.TDelegationToken.class)));
+      tmpMap.put(_Fields.SEC, new org.apache.thrift.meta_data.FieldMetaData("sec", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDelegationToken_result.class, metaDataMap);
+    }
+
+    public getDelegationToken_result() {
+    }
+
+    public getDelegationToken_result(
+      org.apache.accumulo.core.security.thrift.TDelegationToken success,
+      org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec)
+    {
+      this();
+      this.success = success;
+      this.sec = sec;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getDelegationToken_result(getDelegationToken_result other) {
+      if (other.isSetSuccess()) {
+        this.success = new org.apache.accumulo.core.security.thrift.TDelegationToken(other.success);
+      }
+      if (other.isSetSec()) {
+        this.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException(other.sec);
+      }
+    }
+
+    public getDelegationToken_result deepCopy() {
+      return new getDelegationToken_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.sec = null;
+    }
+
+    public org.apache.accumulo.core.security.thrift.TDelegationToken getSuccess() {
+      return this.success;
+    }
+
+    public getDelegationToken_result setSuccess(org.apache.accumulo.core.security.thrift.TDelegationToken success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException getSec() {
+      return this.sec;
+    }
+
+    public getDelegationToken_result setSec(org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException sec) {
+      this.sec = sec;
+      return this;
+    }
+
+    public void unsetSec() {
+      this.sec = null;
+    }
+
+    /** Returns true if field sec is set (has been assigned a value) and false otherwise */
+    public boolean isSetSec() {
+      return this.sec != null;
+    }
+
+    public void setSecIsSet(boolean value) {
+      if (!value) {
+        this.sec = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((org.apache.accumulo.core.security.thrift.TDelegationToken)value);
+        }
+        break;
+
+      case SEC:
+        if (value == null) {
+          unsetSec();
+        } else {
+          setSec((org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case SEC:
+        return getSec();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case SEC:
+        return isSetSec();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getDelegationToken_result)
+        return this.equals((getDelegationToken_result)that);
+      return false;
+    }
+
+    public boolean equals(getDelegationToken_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_sec = true && this.isSetSec();
+      boolean that_present_sec = true && that.isSetSec();
+      if (this_present_sec || that_present_sec) {
+        if (!(this_present_sec && that_present_sec))
+          return false;
+        if (!this.sec.equals(that.sec))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return 0;
+    }
+
+    @Override
+    public int compareTo(getDelegationToken_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetSec()).compareTo(other.isSetSec());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSec()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sec, other.sec);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getDelegationToken_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("sec:");
+      if (this.sec == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.sec);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (success != null) {
+        success.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getDelegationToken_resultStandardSchemeFactory implements SchemeFactory {
+      public getDelegationToken_resultStandardScheme getScheme() {
+        return new getDelegationToken_resultStandardScheme();
+      }
+    }
+
+    private static class getDelegationToken_resultStandardScheme extends StandardScheme<getDelegationToken_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, getDelegationToken_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.success = new org.apache.accumulo.core.security.thrift.TDelegationToken();
+                struct.success.read(iprot);
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // SEC
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException();
+                struct.sec.read(iprot);
+                struct.setSecIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, getDelegationToken_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          struct.success.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.sec != null) {
+          oprot.writeFieldBegin(SEC_FIELD_DESC);
+          struct.sec.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getDelegationToken_resultTupleSchemeFactory implements SchemeFactory {
+      public getDelegationToken_resultTupleScheme getScheme() {
+        return new getDelegationToken_resultTupleScheme();
+      }
+    }
+
+    private static class getDelegationToken_resultTupleScheme extends TupleScheme<getDelegationToken_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetSec()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          struct.success.write(oprot);
+        }
+        if (struct.isSetSec()) {
+          struct.sec.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, getDelegationToken_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = new org.apache.accumulo.core.security.thrift.TDelegationToken();
+          struct.success.read(iprot);
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.sec = new org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException();
+          struct.sec.read(iprot);
+          struct.setSecIsSet(true);
+        }
+      }
+    }
+
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java b/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java
new file mode 100644
index 0000000..18dd7e1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/rpc/SaslClientDigestCallbackHandler.java
@@ -0,0 +1,114 @@
+/*
+ * 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.accumulo.core.rpc;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Arrays;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.RealmCallback;
+import javax.security.sasl.RealmChoiceCallback;
+
+import org.apache.accumulo.core.client.security.tokens.DelegationToken;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Client-side callbackhandler for sasl authentication which is the client-side sibling to the server-side {@link SaslDigestCallbackHandler}. Encoding of name,
+ * password and realm information must be consistent across the pair.
+ */
+public class SaslClientDigestCallbackHandler extends SaslDigestCallbackHandler {
+  private static final Logger log = LoggerFactory.getLogger(SaslClientDigestCallbackHandler.class);
+  private static final String NAME = SaslClientDigestCallbackHandler.class.getSimpleName();
+
+  private final String userName;
+  private final char[] userPassword;
+
+  public SaslClientDigestCallbackHandler(DelegationToken token) {
+    checkNotNull(token);
+    this.userName = encodeIdentifier(token.getIdentifier().getBytes());
+    this.userPassword = encodePassword(token.getPassword());
+  }
+
+  public SaslClientDigestCallbackHandler(String userName, char[] userPassword) {
+    checkNotNull(userName);
+    checkNotNull(userPassword);
+    this.userName = userName;
+    this.userPassword = userPassword;
+  }
+
+  @Override
+  public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
+    NameCallback nc = null;
+    PasswordCallback pc = null;
+    RealmCallback rc = null;
+    for (Callback callback : callbacks) {
+      if (callback instanceof RealmChoiceCallback) {
+        continue;
+      } else if (callback instanceof NameCallback) {
+        nc = (NameCallback) callback;
+      } else if (callback instanceof PasswordCallback) {
+        pc = (PasswordCallback) callback;
+      } else if (callback instanceof RealmCallback) {
+        rc = (RealmCallback) callback;
+      } else {
+        throw new UnsupportedCallbackException(callback, "Unrecognized SASL client callback");
+      }
+    }
+    if (nc != null) {
+      log.debug("SASL client callback: setting username: {}", userName);
+      nc.setName(userName);
+    }
+    if (pc != null) {
+      log.debug("SASL client callback: setting userPassword");
+      pc.setPassword(userPassword);
+    }
+    if (rc != null) {
+      log.debug("SASL client callback: setting realm: {}", rc.getDefaultText());
+      rc.setText(rc.getDefaultText());
+    }
+  }
+
+  @Override
+  public String toString() {
+    return NAME;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder hcb = new HashCodeBuilder(41, 47);
+    hcb.append(userName).append(userPassword);
+    return hcb.toHashCode();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (null == o) {
+      return false;
+    }
+    if (o instanceof SaslClientDigestCallbackHandler) {
+      SaslClientDigestCallbackHandler other = (SaslClientDigestCallbackHandler) o;
+      return userName.equals(other.userName) && Arrays.equals(userPassword, other.userPassword);
+    }
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java b/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java
index e067e23..10438de 100644
--- a/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java
+++ b/core/src/main/java/org/apache/accumulo/core/rpc/SaslConnectionParams.java
@@ -16,6 +16,8 @@
  */
 package org.apache.accumulo.core.rpc;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.io.IOException;
 import java.util.Collections;
 import java.util.HashMap;
@@ -23,10 +25,14 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import javax.security.auth.callback.CallbackHandler;
 import javax.security.sasl.Sasl;
 
 import org.apache.accumulo.core.client.ClientConfiguration;
 import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.accumulo.core.client.security.tokens.DelegationToken;
+import org.apache.accumulo.core.client.security.tokens.KerberosToken;
 import org.apache.accumulo.core.conf.AccumuloConfiguration;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.commons.configuration.MapConfiguration;
@@ -79,6 +85,34 @@ public class SaslConnectionParams {
     }
   }
 
+  /**
+   * The SASL mechanism to use for authentication
+   */
+  public enum SaslMechanism {
+    GSSAPI("GSSAPI"), // Kerberos
+    DIGEST_MD5("DIGEST-MD5"); // Delegation Tokens
+
+    private final String mechanismName;
+
+    private SaslMechanism(String mechanismName) {
+      this.mechanismName = mechanismName;
+    }
+
+    public String getMechanismName() {
+      return mechanismName;
+    }
+
+    public static SaslMechanism get(String mechanismName) {
+      if (GSSAPI.mechanismName.equals(mechanismName)) {
+        return GSSAPI;
+      } else if (DIGEST_MD5.mechanismName.equals(mechanismName)) {
+        return DIGEST_MD5;
+      }
+
+      throw new IllegalArgumentException("No value for " + mechanismName);
+    }
+  }
+
   private static String defaultRealm;
 
   static {
@@ -90,25 +124,47 @@ public class SaslConnectionParams {
     }
   }
 
-  private String principal;
-  private QualityOfProtection qop;
-  private String kerberosServerPrimary;
-  private final Map<String,String> saslProperties;
-
-  private SaslConnectionParams() {
-    saslProperties = new HashMap<>();
-  }
+  protected String principal;
+  protected QualityOfProtection qop;
+  protected String kerberosServerPrimary;
+  protected SaslMechanism mechanism;
+  protected CallbackHandler callbackHandler;
+  protected final Map<String,String> saslProperties;
 
   /**
    * Generate an {@link SaslConnectionParams} instance given the provided {@link AccumuloConfiguration}. The provided configuration is converted into a
    * {@link ClientConfiguration}, ignoring any properties which are not {@link ClientProperty}s. If SASL is not being used, a null object will be returned.
    * Callers should strive to use {@link #forConfig(ClientConfiguration)}; server processes are the only intended consumers of this method.
    *
-   * @param conf
-   *          The configuration for clients to communicate with Accumulo
-   * @return An {@link SaslConnectionParams} instance or null if SASL is not enabled
    */
-  public static SaslConnectionParams forConfig(AccumuloConfiguration conf) {
+  public SaslConnectionParams(AccumuloConfiguration conf, AuthenticationToken token) {
+    this(new ClientConfiguration(new MapConfiguration(getProperties(conf))), token);
+  }
+
+  public SaslConnectionParams(ClientConfiguration conf, AuthenticationToken token) {
+    checkNotNull(conf, "Configuration was null");
+    checkNotNull(token, "AuthenticationToken was null");
+
+    saslProperties = new HashMap<>();
+    updatePrincipalFromUgi();
+    updateFromConfiguration(conf);
+    updateFromToken(token);
+  }
+
+  protected void updateFromToken(AuthenticationToken token) {
+    if (token instanceof KerberosToken) {
+      mechanism = SaslMechanism.GSSAPI;
+      // No callbackhandlers necessary for GSSAPI
+      callbackHandler = null;
+    } else if (token instanceof DelegationToken) {
+      mechanism = SaslMechanism.DIGEST_MD5;
+      callbackHandler = new SaslClientDigestCallbackHandler((DelegationToken) token);
+    } else {
+      throw new IllegalArgumentException("Cannot determine SASL mechanism for token class: " + token.getClass());
+    }
+  }
+
+  protected static Map<String,String> getProperties(AccumuloConfiguration conf) {
     final Map<String,String> clientProperties = new HashMap<>();
 
     // Servers will only have the full principal in their configuration -- parse the
@@ -136,25 +192,10 @@ public class SaslConnectionParams {
       }
     }
 
-    ClientConfiguration clientConf = new ClientConfiguration(new MapConfiguration(clientProperties));
-    return forConfig(clientConf);
+    return clientProperties;
   }
 
-  /**
-   * Generate an {@link SaslConnectionParams} instance given the provided {@link ClientConfiguration}. If SASL is not being used, a null object will be
-   * returned.
-   *
-   * @param conf
-   *          The configuration for clients to communicate with Accumulo
-   * @return An {@link SaslConnectionParams} instance or null if SASL is not enabled
-   */
-  public static SaslConnectionParams forConfig(ClientConfiguration conf) {
-    if (!Boolean.parseBoolean(conf.get(ClientProperty.INSTANCE_RPC_SASL_ENABLED))) {
-      return null;
-    }
-
-    SaslConnectionParams params = new SaslConnectionParams();
-
+  protected void updatePrincipalFromUgi() {
     // Ensure we're using Kerberos auth for Hadoop UGI
     if (!UserGroupInformation.isSecurityEnabled()) {
       throw new RuntimeException("Cannot use SASL if Hadoop security is not enabled");
@@ -169,22 +210,23 @@ public class SaslConnectionParams {
     }
 
     // The full name is our principal
-    params.principal = currentUser.getUserName();
-    if (null == params.principal) {
+    this.principal = currentUser.getUserName();
+    if (null == this.principal) {
       throw new RuntimeException("Got null username from " + currentUser);
     }
 
+  }
+
+  protected void updateFromConfiguration(ClientConfiguration conf) {
     // Get the quality of protection to use
     final String qopValue = conf.get(ClientProperty.RPC_SASL_QOP);
-    params.qop = QualityOfProtection.get(qopValue);
+    this.qop = QualityOfProtection.get(qopValue);
 
     // Add in the SASL properties to a map so we don't have to repeatedly construct this map
-    params.saslProperties.put(Sasl.QOP, params.qop.getQuality());
+    this.saslProperties.put(Sasl.QOP, this.qop.getQuality());
 
     // The primary from the KRB principal on each server (e.g. primary/instance@realm)
-    params.kerberosServerPrimary = conf.get(ClientProperty.KERBEROS_SERVER_PRIMARY);
-
-    return params;
+    this.kerberosServerPrimary = conf.get(ClientProperty.KERBEROS_SERVER_PRIMARY);
   }
 
   public Map<String,String> getSaslProperties() {
@@ -211,10 +253,24 @@ public class SaslConnectionParams {
     return principal;
   }
 
+  /**
+   * The SASL mechanism to use for authentication
+   */
+  public SaslMechanism getMechanism() {
+    return mechanism;
+  }
+
+  /**
+   * The SASL callback handler for this mechanism, may be null.
+   */
+  public CallbackHandler getCallbackHandler() {
+    return callbackHandler;
+  }
+
   @Override
   public int hashCode() {
     HashCodeBuilder hcb = new HashCodeBuilder(23,29);
-    hcb.append(kerberosServerPrimary).append(saslProperties).append(qop.hashCode()).append(principal);
+    hcb.append(kerberosServerPrimary).append(saslProperties).append(qop.hashCode()).append(principal).append(mechanism).append(callbackHandler);
     return hcb.toHashCode();
   }
 
@@ -231,6 +287,16 @@ public class SaslConnectionParams {
       if (!principal.equals(other.principal)) {
         return false;
       }
+      if (!mechanism.equals(other.mechanism)) {
+        return false;
+      }
+      if (null == callbackHandler) {
+        if (null != other.callbackHandler) {
+          return false;
+        }
+      } else if (!callbackHandler.equals(other.callbackHandler)) {
+        return false;
+      }
 
       return saslProperties.equals(other.saslProperties);
     }
@@ -238,6 +304,14 @@ public class SaslConnectionParams {
     return false;
   }
 
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder(64);
+    sb.append("SaslConnectionParams[").append("kerberosServerPrimary=").append(kerberosServerPrimary).append(", qualityOfProtection=").append(qop);
+    sb.append(", principal=").append(principal).append(", mechanism=").append(mechanism).append(", callbackHandler=").append(callbackHandler).append("]");
+    return sb.toString();
+  }
+
   public static String getDefaultRealm() {
     return defaultRealm;
   }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java b/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java
new file mode 100644
index 0000000..901bec1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/rpc/SaslDigestCallbackHandler.java
@@ -0,0 +1,77 @@
+/*
+ * 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.accumulo.core.rpc;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.security.token.SecretManager;
+import org.apache.hadoop.security.token.SecretManager.InvalidToken;
+import org.apache.hadoop.security.token.TokenIdentifier;
+
+/**
+ * Common serialization methods across the client and server callback handlers for SASL. Serialization and deserialization methods must be kept in sync.
+ */
+public abstract class SaslDigestCallbackHandler implements CallbackHandler {
+
+  /**
+   * Encode the serialized {@link TokenIdentifier} into a {@link String}.
+   *
+   * @param identifier
+   *          The serialized identifier
+   * @see #decodeIdentifier(String)
+   */
+  public String encodeIdentifier(byte[] identifier) {
+    return new String(Base64.encodeBase64(identifier));
+  }
+
+  /**
+   * Encode the token password into a character array.
+   *
+   * @param password
+   *          The token password
+   * @see #getPassword(SecretManager, TokenIdentifier)
+   */
+  public char[] encodePassword(byte[] password) {
+    return new String(Base64.encodeBase64(password)).toCharArray();
+  }
+
+  /**
+   * Generate the password from the provided {@link SecretManager} and {@link TokenIdentifier}.
+   *
+   * @param secretManager
+   *          The server SecretManager
+   * @param tokenid
+   *          The TokenIdentifier from the client
+   * @see #encodePassword(byte[])
+   */
+  public <T extends TokenIdentifier> char[] getPassword(SecretManager<T> secretManager, T tokenid) throws InvalidToken {
+    return encodePassword(secretManager.retrievePassword(tokenid));
+  }
+
+  /**
+   * Decode the encoded {@link TokenIdentifier} into bytes suitable to reconstitute the identifier.
+   *
+   * @param identifier
+   *          The encoded, serialized {@link TokenIdentifier}
+   * @see #encodeIdentifier(byte[])
+   */
+  public byte[] decodeIdentifier(String identifier) {
+    return Base64.decodeBase64(identifier.getBytes());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java b/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java
index d880fb3..51dd5ba 100644
--- a/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java
+++ b/core/src/main/java/org/apache/accumulo/core/rpc/ThriftUtil.java
@@ -36,6 +36,7 @@ import org.apache.accumulo.core.client.impl.ClientExec;
 import org.apache.accumulo.core.client.impl.ClientExecReturn;
 import org.apache.accumulo.core.client.impl.ThriftTransportPool;
 import org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException;
+import org.apache.accumulo.core.rpc.SaslConnectionParams.SaslMechanism;
 import org.apache.accumulo.core.tabletserver.thrift.TabletClientService;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.hadoop.security.UserGroupInformation;
@@ -65,7 +66,7 @@ public class ThriftUtil {
   private static final TFramedTransport.Factory transportFactory = new TFramedTransport.Factory(Integer.MAX_VALUE);
   private static final Map<Integer,TTransportFactory> factoryCache = new HashMap<Integer,TTransportFactory>();
 
-  public static final String GSSAPI = "GSSAPI";
+  public static final String GSSAPI = "GSSAPI", DIGEST_MD5 = "DIGEST-MD5";
 
   /**
    * An instance of {@link TraceProtocolFactory}
@@ -252,7 +253,7 @@ public class ThriftUtil {
    *          RPC options
    */
   public static TTransport createTransport(HostAndPort address, ClientContext context) throws TException {
-    return createClientTransport(address, (int) context.getClientTimeoutInMillis(), context.getClientSslParams(), context.getClientSaslParams());
+    return createClientTransport(address, (int) context.getClientTimeoutInMillis(), context.getClientSslParams(), context.getSaslParams());
   }
 
   /**
@@ -345,11 +346,14 @@ public class ThriftUtil {
           // Is this pricey enough that we want to cache it?
           final String hostname = InetAddress.getByName(address.getHostText()).getCanonicalHostName();
 
-          log.trace("Opening transport to server as {} to {}/{}", currentUser, saslParams.getKerberosServerPrimary(), hostname);
+          final SaslMechanism mechanism = saslParams.getMechanism();
+
+          log.trace("Opening transport to server as {} to {}/{} using {}", currentUser, saslParams.getKerberosServerPrimary(), hostname, mechanism);
 
           // Create the client SASL transport using the information for the server
           // Despite the 'protocol' argument seeming to be useless, it *must* be the primary of the server being connected to
-          transport = new TSaslClientTransport(GSSAPI, null, saslParams.getKerberosServerPrimary(), hostname, saslParams.getSaslProperties(), null, transport);
+          transport = new TSaslClientTransport(mechanism.getMechanismName(), null, saslParams.getKerberosServerPrimary(), hostname,
+              saslParams.getSaslProperties(), saslParams.getCallbackHandler(), transport);
 
           // Wrap it all in a processor which will run with a doAs the current user
           transport = new UGIAssumingTransport(transport, currentUser);

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java b/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java
new file mode 100644
index 0000000..0b671d8
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/security/AuthenticationTokenIdentifier.java
@@ -0,0 +1,210 @@
+/*
+ * 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.accumulo.core.security;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.accumulo.core.client.admin.DelegationTokenConfig;
+import org.apache.accumulo.core.security.thrift.TAuthenticationTokenIdentifier;
+import org.apache.accumulo.core.util.ThriftMessageUtil;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.security.token.TokenIdentifier;
+
+/**
+ * Implementation that identifies the underlying {@link Token} for Accumulo.
+ */
+public class AuthenticationTokenIdentifier extends TokenIdentifier {
+  public static final Text TOKEN_KIND = new Text("ACCUMULO_AUTH_TOKEN");
+
+  private TAuthenticationTokenIdentifier impl = null;
+  private DelegationTokenConfig cfg = null;
+
+  public AuthenticationTokenIdentifier() {
+    // noop for Writable
+  }
+
+  public AuthenticationTokenIdentifier(String principal) {
+    this(principal, null);
+  }
+
+  public AuthenticationTokenIdentifier(String principal, DelegationTokenConfig cfg) {
+    checkNotNull(principal);
+    impl = new TAuthenticationTokenIdentifier(principal);
+    this.cfg = cfg;
+  }
+
+  public AuthenticationTokenIdentifier(String principal, int keyId, long issueDate, long expirationDate, String instanceId) {
+    checkNotNull(principal);
+    impl = new TAuthenticationTokenIdentifier(principal);
+    impl.setKeyId(keyId);
+    impl.setIssueDate(issueDate);
+    impl.setExpirationDate(expirationDate);
+    impl.setInstanceId(instanceId);
+  }
+
+  public AuthenticationTokenIdentifier(AuthenticationTokenIdentifier identifier) {
+    checkNotNull(identifier);
+    impl = new TAuthenticationTokenIdentifier(identifier.getThriftIdentifier());
+  }
+
+  public AuthenticationTokenIdentifier(TAuthenticationTokenIdentifier identifier) {
+    checkNotNull(identifier);
+    impl = new TAuthenticationTokenIdentifier(identifier);
+  }
+
+  public void setKeyId(int keyId) {
+    impl.setKeyId(keyId);
+  }
+
+  public int getKeyId() {
+    checkNotNull(impl, "Identifier not initialized");
+    return impl.getKeyId();
+  }
+
+  public void setIssueDate(long issueDate) {
+    checkNotNull(impl, "Identifier not initialized");
+    impl.setIssueDate(issueDate);
+  }
+
+  public long getIssueDate() {
+    checkNotNull(impl, "Identifier not initialized");
+    return impl.getIssueDate();
+  }
+
+  public void setExpirationDate(long expirationDate) {
+    checkNotNull(impl, "Identifier not initialized");
+    impl.setExpirationDate(expirationDate);
+  }
+
+  public long getExpirationDate() {
+    checkNotNull(impl, "Identifier not initialized");
+    return impl.getExpirationDate();
+  }
+
+  public void setInstanceId(String instanceId) {
+    checkNotNull(impl, "Identifier not initialized");
+    impl.setInstanceId(instanceId);
+  }
+
+  public String getInstanceId() {
+    checkNotNull(impl, "Identifier not initialized");
+    return impl.getInstanceId();
+  }
+
+  public TAuthenticationTokenIdentifier getThriftIdentifier() {
+    checkNotNull(impl);
+    return impl;
+  }
+
+  /**
+   * A configuration from the requesting user, may be null.
+   */
+  public DelegationTokenConfig getConfig() {
+    return cfg;
+  }
+
+  @Override
+  public void write(DataOutput out) throws IOException {
+    if (null != impl) {
+      ThriftMessageUtil msgUtil = new ThriftMessageUtil();
+      ByteBuffer serialized = msgUtil.serialize(impl);
+      out.writeInt(serialized.limit());
+      out.write(serialized.array(), serialized.arrayOffset(), serialized.limit());
+    } else {
+      out.writeInt(0);
+    }
+  }
+
+  @Override
+  public void readFields(DataInput in) throws IOException {
+    int length = in.readInt();
+    if (length > 0) {
+      ThriftMessageUtil msgUtil = new ThriftMessageUtil();
+      byte[] serialized = new byte[length];
+      in.readFully(serialized);
+      impl = new TAuthenticationTokenIdentifier();
+      msgUtil.deserialize(serialized, impl);
+    }
+  }
+
+  @Override
+  public Text getKind() {
+    return TOKEN_KIND;
+  }
+
+  @Override
+  public UserGroupInformation getUser() {
+    if (null != impl && impl.isSetPrincipal()) {
+      return UserGroupInformation.createRemoteUser(impl.getPrincipal());
+    }
+    return null;
+  }
+
+  @Override
+  public int hashCode() {
+    if (null == impl) {
+      return 0;
+    }
+    HashCodeBuilder hcb = new HashCodeBuilder(7, 11);
+    if (impl.isSetPrincipal()) {
+      hcb.append(impl.getPrincipal());
+    }
+    if (impl.isSetKeyId()) {
+      hcb.append(impl.getKeyId());
+    }
+    if (impl.isSetIssueDate()) {
+      hcb.append(impl.getIssueDate());
+    }
+    if (impl.isSetExpirationDate()) {
+      hcb.append(impl.getExpirationDate());
+    }
+    if (impl.isSetInstanceId()) {
+      hcb.append(impl.getInstanceId());
+    }
+    return hcb.toHashCode();
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder(128);
+    sb.append("AuthenticationTokenIdentifier(").append(impl).append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (null == o) {
+      return false;
+    }
+    if (o instanceof AuthenticationTokenIdentifier) {
+      AuthenticationTokenIdentifier other = (AuthenticationTokenIdentifier) o;
+      if (null == impl) {
+        return null == other.impl;
+      }
+      return impl.equals(other.impl);
+    }
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2c983317/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java b/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
index b998179..a1df5dc 100644
--- a/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
+++ b/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
@@ -37,7 +37,8 @@ public enum SystemPermission {
   SYSTEM((byte) 7),
   CREATE_NAMESPACE((byte) 8),
   DROP_NAMESPACE((byte) 9),
-  ALTER_NAMESPACE((byte) 10);
+  ALTER_NAMESPACE((byte) 10),
+  OBTAIN_DELEGATION_TOKEN((byte) 11);
 
   private byte permID;