tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Glossaries     Architecture     IMS     UICC    |    search     info

RFC 5661

 
 
 

Network File System (NFS) Version 4 Minor Version 1 Protocol

Part 17 of 20, p. 491 to 525
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 491 
18.33.  Operation 40: BACKCHANNEL_CTL - Backchannel Control

18.33.1.  ARGUMENT

   typedef opaque gsshandle4_t<>;

   struct gss_cb_handles4 {
           rpc_gss_svc_t           gcbp_service; /* RFC 2203 */
           gsshandle4_t            gcbp_handle_from_server;
           gsshandle4_t            gcbp_handle_from_client;
   };

   union callback_sec_parms4 switch (uint32_t cb_secflavor) {
   case AUTH_NONE:
           void;
   case AUTH_SYS:
           authsys_parms   cbsp_sys_cred; /* RFC 1831 */
   case RPCSEC_GSS:
           gss_cb_handles4 cbsp_gss_handles;
   };

   struct BACKCHANNEL_CTL4args {
           uint32_t                bca_cb_program;
           callback_sec_parms4     bca_sec_parms<>;
   };

18.33.2.  RESULT

   struct BACKCHANNEL_CTL4res {
           nfsstat4                bcr_status;
   };

Top      Up      ToC       Page 492 
18.33.3.  DESCRIPTION

   The BACKCHANNEL_CTL operation replaces the backchannel's callback
   program number and adds (not replaces) RPCSEC_GSS handles for use by
   the backchannel.

   The arguments of the BACKCHANNEL_CTL call are a subset of the
   CREATE_SESSION parameters.  In the arguments of BACKCHANNEL_CTL, the
   bca_cb_program field and bca_sec_parms fields correspond respectively
   to the csa_cb_program and csa_sec_parms fields of the arguments of
   CREATE_SESSION (Section 18.36).

   BACKCHANNEL_CTL MUST appear in a COMPOUND that starts with SEQUENCE.

   If the RPCSEC_GSS handle identified by gcbp_handle_from_server does
   not exist on the server, the server MUST return NFS4ERR_NOENT.

   If an RPCSEC_GSS handle is using the SSV context (see
   Section 2.10.9), then because each SSV RPCSEC_GSS handle shares a
   common SSV GSS context, there are security considerations specific to
   this situation discussed in Section 2.10.10.

18.34.  Operation 41: BIND_CONN_TO_SESSION - Associate Connection with
        Session

18.34.1.  ARGUMENT

   enum channel_dir_from_client4 {
    CDFC4_FORE             = 0x1,
    CDFC4_BACK             = 0x2,
    CDFC4_FORE_OR_BOTH     = 0x3,
    CDFC4_BACK_OR_BOTH     = 0x7
   };

   struct BIND_CONN_TO_SESSION4args {
    sessionid4     bctsa_sessid;

    channel_dir_from_client4
                   bctsa_dir;

    bool           bctsa_use_conn_in_rdma_mode;
   };

Top      Up      ToC       Page 493 
18.34.2.  RESULT

   enum channel_dir_from_server4 {
    CDFS4_FORE     = 0x1,
    CDFS4_BACK     = 0x2,
    CDFS4_BOTH     = 0x3
   };

   struct BIND_CONN_TO_SESSION4resok {
    sessionid4     bctsr_sessid;

    channel_dir_from_server4
                   bctsr_dir;

    bool           bctsr_use_conn_in_rdma_mode;
   };

   union BIND_CONN_TO_SESSION4res
    switch (nfsstat4 bctsr_status) {

    case NFS4_OK:
     BIND_CONN_TO_SESSION4resok
                   bctsr_resok4;

    default:       void;
   };

18.34.3.  DESCRIPTION

   BIND_CONN_TO_SESSION is used to associate additional connections with
   a session.  It MUST be used on the connection being associated with
   the session.  It MUST be the only operation in the COMPOUND
   procedure.  If SP4_NONE (Section 18.35) state protection is used, any
   principal, security flavor, or RPCSEC_GSS context MAY be used to
   invoke the operation.  If SP4_MACH_CRED is used, RPCSEC_GSS MUST be
   used with the integrity or privacy services, using the principal that
   created the client ID.  If SP4_SSV is used, RPCSEC_GSS with the SSV
   GSS mechanism (Section 2.10.9) and integrity or privacy MUST be used.

   If, when the client ID was created, the client opted for SP4_NONE
   state protection, the client is not required to use
   BIND_CONN_TO_SESSION to associate the connection with the session,
   unless the client wishes to associate the connection with the
   backchannel.  When SP4_NONE protection is used, simply sending a
   COMPOUND request with a SEQUENCE operation is sufficient to associate
   the connection with the session specified in SEQUENCE.

Top      Up      ToC       Page 494 
   The field bctsa_dir indicates whether the client wants to associate
   the connection with the fore channel or the backchannel or both
   channels.  The value CDFC4_FORE_OR_BOTH indicates that the client
   wants to associate the connection with both the fore channel and
   backchannel, but will accept the connection being associated to just
   the fore channel.  The value CDFC4_BACK_OR_BOTH indicates that the
   client wants to associate with both the fore channel and backchannel,
   but will accept the connection being associated with just the
   backchannel.  The server replies in bctsr_dir which channel(s) the
   connection is associated with.  If the client specified CDFC4_FORE,
   the server MUST return CDFS4_FORE.  If the client specified
   CDFC4_BACK, the server MUST return CDFS4_BACK.  If the client
   specified CDFC4_FORE_OR_BOTH, the server MUST return CDFS4_FORE or
   CDFS4_BOTH.  If the client specified CDFC4_BACK_OR_BOTH, the server
   MUST return CDFS4_BACK or CDFS4_BOTH.

   See the CREATE_SESSION operation (Section 18.36), and the description
   of the argument csa_use_conn_in_rdma_mode to understand
   bctsa_use_conn_in_rdma_mode, and the description of
   csr_use_conn_in_rdma_mode to understand bctsr_use_conn_in_rdma_mode.

   Invoking BIND_CONN_TO_SESSION on a connection already associated with
   the specified session has no effect, and the server MUST respond with
   NFS4_OK, unless the client is demanding changes to the set of
   channels the connection is associated with.  If so, the server MUST
   return NFS4ERR_INVAL.

18.34.4.  IMPLEMENTATION

   If a session's channel loses all connections, depending on the client
   ID's state protection and type of channel, the client might need to
   use BIND_CONN_TO_SESSION to associate a new connection.  If the
   server restarted and does not keep the reply cache in stable storage,
   the server will not recognize the session ID.  The client will
   ultimately have to invoke EXCHANGE_ID to create a new client ID and
   session.

   Suppose SP4_SSV state protection is being used, and
   BIND_CONN_TO_SESSION is among the operations included in the
   spo_must_enforce set when the client ID was created (Section 18.35).
   If so, there is an issue if SET_SSV is sent, no response is returned,
   and the last connection associated with the client ID drops.  The
   client, per the sessions model, MUST retry the SET_SSV.  But it needs
   a new connection to do so, and MUST associate that connection with
   the session via a BIND_CONN_TO_SESSION authenticated with the SSV GSS
   mechanism.  The problem is that the RPCSEC_GSS message integrity

Top      Up      ToC       Page 495 
   codes use a subkey derived from the SSV as the key and the SSV may
   have changed.  While there are multiple recovery strategies, a
   single, general strategy is described here.

   o  The client reconnects.

   o  The client assumes that the SET_SSV was executed, and so sends
      BIND_CONN_TO_SESSION with the subkey (derived from the new SSV,
      i.e., what SET_SSV would have set the SSV to) used as the key for
      the RPCSEC_GSS credential message integrity codes.

   o  If the request succeeds, this means that the original attempted
      SET_SSV did execute successfully.  The client re-sends the
      original SET_SSV, which the server will reply to via the reply
      cache.

   o  If the server returns an RPC authentication error, this means that
      the server's current SSV was not changed (and the SET_SSV was
      likely not executed).  The client then tries BIND_CONN_TO_SESSION
      with the subkey derived from the old SSV as the key for the
      RPCSEC_GSS message integrity codes.

   o  The attempted BIND_CONN_TO_SESSION with the old SSV should
      succeed.  If so, the client re-sends the original SET_SSV.  If the
      original SET_SSV was not executed, then the server executes it.
      If the original SET_SSV was executed but failed, the server will
      return the SET_SSV from the reply cache.

18.35.  Operation 42: EXCHANGE_ID - Instantiate Client ID

   The EXCHANGE_ID exchanges long-hand client and server identifiers
   (owners), and creates a client ID.

18.35.1.  ARGUMENT

   const EXCHGID4_FLAG_SUPP_MOVED_REFER    = 0x00000001;
   const EXCHGID4_FLAG_SUPP_MOVED_MIGR     = 0x00000002;

   const EXCHGID4_FLAG_BIND_PRINC_STATEID  = 0x00000100;

   const EXCHGID4_FLAG_USE_NON_PNFS        = 0x00010000;
   const EXCHGID4_FLAG_USE_PNFS_MDS        = 0x00020000;
   const EXCHGID4_FLAG_USE_PNFS_DS         = 0x00040000;

   const EXCHGID4_FLAG_MASK_PNFS           = 0x00070000;

   const EXCHGID4_FLAG_UPD_CONFIRMED_REC_A = 0x40000000;
   const EXCHGID4_FLAG_CONFIRMED_R         = 0x80000000;

Top      Up      ToC       Page 496 
   struct state_protect_ops4 {
           bitmap4 spo_must_enforce;
           bitmap4 spo_must_allow;
   };

   struct ssv_sp_parms4 {
           state_protect_ops4      ssp_ops;
           sec_oid4                ssp_hash_algs<>;
           sec_oid4                ssp_encr_algs<>;
           uint32_t                ssp_window;
           uint32_t                ssp_num_gss_handles;
   };

   enum state_protect_how4 {
           SP4_NONE = 0,
           SP4_MACH_CRED = 1,
           SP4_SSV = 2
   };

   union state_protect4_a switch(state_protect_how4 spa_how) {
           case SP4_NONE:
                   void;
           case SP4_MACH_CRED:
                   state_protect_ops4      spa_mach_ops;
           case SP4_SSV:
                   ssv_sp_parms4           spa_ssv_parms;
   };

   struct EXCHANGE_ID4args {
           client_owner4           eia_clientowner;
           uint32_t                eia_flags;
           state_protect4_a        eia_state_protect;
           nfs_impl_id4            eia_client_impl_id<1>;
   };

18.35.2.  RESULT

   struct ssv_prot_info4 {
    state_protect_ops4     spi_ops;
    uint32_t               spi_hash_alg;
    uint32_t               spi_encr_alg;
    uint32_t               spi_ssv_len;
    uint32_t               spi_window;
    gsshandle4_t           spi_handles<>;
   };

Top      Up      ToC       Page 497 
   union state_protect4_r switch(state_protect_how4 spr_how) {
    case SP4_NONE:
            void;
    case SP4_MACH_CRED:
            state_protect_ops4     spr_mach_ops;
    case SP4_SSV:
            ssv_prot_info4         spr_ssv_info;
   };

   struct EXCHANGE_ID4resok {
    clientid4        eir_clientid;
    sequenceid4      eir_sequenceid;
    uint32_t         eir_flags;
    state_protect4_r eir_state_protect;
    server_owner4    eir_server_owner;
    opaque           eir_server_scope<NFS4_OPAQUE_LIMIT>;
    nfs_impl_id4     eir_server_impl_id<1>;
   };

   union EXCHANGE_ID4res switch (nfsstat4 eir_status) {
   case NFS4_OK:
    EXCHANGE_ID4resok      eir_resok4;

   default:
    void;
   };

18.35.3.  DESCRIPTION

   The client uses the EXCHANGE_ID operation to register a particular
   client owner with the server.  The client ID returned from this
   operation will be necessary for requests that create state on the
   server and will serve as a parent object to sessions created by the
   client.  In order to confirm the client ID it must first be used,
   along with the returned eir_sequenceid, as arguments to
   CREATE_SESSION.  If the flag EXCHGID4_FLAG_CONFIRMED_R is set in the
   result, eir_flags, then eir_sequenceid MUST be ignored, as it has no
   relevancy.

   EXCHANGE_ID MAY be sent in a COMPOUND procedure that starts with
   SEQUENCE.  However, when a client communicates with a server for the
   first time, it will not have a session, so using SEQUENCE will not be
   possible.  If EXCHANGE_ID is sent without a preceding SEQUENCE, then
   it MUST be the only operation in the COMPOUND procedure's request.
   If it is not, the server MUST return NFS4ERR_NOT_ONLY_OP.

Top      Up      ToC       Page 498 
   The eia_clientowner field is composed of a co_verifier field and a
   co_ownerid string.  As noted in Section 2.4, the co_ownerid describes
   the client, and the co_verifier is the incarnation of the client.  An
   EXCHANGE_ID sent with a new incarnation of the client will lead to
   the server removing lock state of the old incarnation.  Whereas an
   EXCHANGE_ID sent with the current incarnation and co_ownerid will
   result in an error or an update of the client ID's properties,
   depending on the arguments to EXCHANGE_ID.

   A server MUST NOT use the same client ID for two different
   incarnations of an eir_clientowner.

   In addition to the client ID and sequence ID, the server returns a
   server owner (eir_server_owner) and server scope (eir_server_scope).
   The former field is used for network trunking as described in
   Section 2.10.5.  The latter field is used to allow clients to
   determine when client IDs sent by one server may be recognized by
   another in the event of file system migration (see Section 11.7.7).

   The client ID returned by EXCHANGE_ID is only unique relative to the
   combination of eir_server_owner.so_major_id and eir_server_scope.
   Thus, if two servers return the same client ID, the onus is on the
   client to distinguish the client IDs on the basis of
   eir_server_owner.so_major_id and eir_server_scope.  In the event two
   different servers claim matching server_owner.so_major_id and
   eir_server_scope, the client can use the verification techniques
   discussed in Section 2.10.5 to determine if the servers are distinct.
   If they are distinct, then the client will need to note the
   destination network addresses of the connections used with each
   server, and use the network address as the final discriminator.

   The server, as defined by the unique identity expressed in the
   so_major_id of the server owner and the server scope, needs to track
   several properties of each client ID it hands out.  The properties
   apply to the client ID and all sessions associated with the client
   ID.  The properties are derived from the arguments and results of
   EXCHANGE_ID.  The client ID properties include:

   o  The capabilities expressed by the following bits, which come from
      the results of EXCHANGE_ID:

      *  EXCHGID4_FLAG_SUPP_MOVED_REFER

      *  EXCHGID4_FLAG_SUPP_MOVED_MIGR

      *  EXCHGID4_FLAG_BIND_PRINC_STATEID

      *  EXCHGID4_FLAG_USE_NON_PNFS

Top      Up      ToC       Page 499 
      *  EXCHGID4_FLAG_USE_PNFS_MDS

      *  EXCHGID4_FLAG_USE_PNFS_DS

      These properties may be updated by subsequent EXCHANGE_ID requests
      on confirmed client IDs though the server MAY refuse to change
      them.

   o  The state protection method used, one of SP4_NONE, SP4_MACH_CRED,
      or SP4_SSV, as set by the spa_how field of the arguments to
      EXCHANGE_ID.  Once the client ID is confirmed, this property
      cannot be updated by subsequent EXCHANGE_ID requests.

   o  For SP4_MACH_CRED or SP4_SSV state protection:

      *  The list of operations (spo_must_enforce) that MUST use the
         specified state protection.  This list comes from the results
         of EXCHANGE_ID.

      *  The list of operations (spo_must_allow) that MAY use the
         specified state protection.  This list comes from the results
         of EXCHANGE_ID.

      Once the client ID is confirmed, these properties cannot be
      updated by subsequent EXCHANGE_ID requests.

   o  For SP4_SSV protection:

      *  The OID of the hash algorithm.  This property is represented by
         one of the algorithms in the ssp_hash_algs field of the
         EXCHANGE_ID arguments.  Once the client ID is confirmed, this
         property cannot be updated by subsequent EXCHANGE_ID requests.

      *  The OID of the encryption algorithm.  This property is
         represented by one of the algorithms in the ssp_encr_algs field
         of the EXCHANGE_ID arguments.  Once the client ID is confirmed,
         this property cannot be updated by subsequent EXCHANGE_ID
         requests.

      *  The length of the SSV.  This property is represented by the
         spi_ssv_len field in the EXCHANGE_ID results.  Once the client
         ID is confirmed, this property cannot be updated by subsequent
         EXCHANGE_ID requests.

         There are REQUIRED and RECOMMENDED relationships among the
         length of the key of the encryption algorithm ("key length"),
         the length of the output of hash algorithm ("hash length"), and
         the length of the SSV ("SSV length").

Top      Up      ToC       Page 500 
         +  key length MUST be <= hash length.  This is because the keys
            used for the encryption algorithm are actually subkeys
            derived from the SSV, and the derivation is via the hash
            algorithm.  The selection of an encryption algorithm with a
            key length that exceeded the length of the output of the
            hash algorithm would require padding, and thus weaken the
            use of the encryption algorithm.

         +  hash length SHOULD be <= SSV length.  This is because the
            SSV is a key used to derive subkeys via an HMAC, and it is
            recommended that the key used as input to an HMAC be at
            least as long as the length of the HMAC's hash algorithm's
            output (see Section 3 of RFC2104 [11]).

         +  key length SHOULD be <= SSV length.  This is a transitive
            result of the above two invariants.

         +  key length SHOULD be >= hash length / 2.  This is because
            the subkey derivation is via an HMAC and it is recommended
            that if the HMAC has to be truncated, it should not be
            truncated to less than half the hash length (see Section 4
            of RFC2104 [11]).

      *  Number of concurrent versions of the SSV the client and server
         will support (Section 2.10.9).  This property is represented by
         spi_window in the EXCHANGE_ID results.  The property may be
         updated by subsequent EXCHANGE_ID requests.

   o  The client's implementation ID as represented by the
      eia_client_impl_id field of the arguments.  The property may be
      updated by subsequent EXCHANGE_ID requests.

   o  The server's implementation ID as represented by the
      eir_server_impl_id field of the reply.  The property may be
      updated by replies to subsequent EXCHANGE_ID requests.

   The eia_flags passed as part of the arguments and the eir_flags
   results allow the client and server to inform each other of their
   capabilities as well as indicate how the client ID will be used.
   Whether a bit is set or cleared on the arguments' flags does not
   force the server to set or clear the same bit on the results' side.
   Bits not defined above cannot be set in the eia_flags field.  If they
   are, the server MUST reject the operation with NFS4ERR_INVAL.

   The EXCHGID4_FLAG_UPD_CONFIRMED_REC_A bit can only be set in
   eia_flags; it is always off in eir_flags.  The
   EXCHGID4_FLAG_CONFIRMED_R bit can only be set in eir_flags; it is
   always off in eia_flags.  If the server recognizes the co_ownerid and

Top      Up      ToC       Page 501 
   co_verifier as mapping to a confirmed client ID, it sets
   EXCHGID4_FLAG_CONFIRMED_R in eir_flags.  The
   EXCHGID4_FLAG_CONFIRMED_R flag allows a client to tell if the client
   ID it is trying to create already exists and is confirmed.

   If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set in eia_flags, this means
   that the client is attempting to update properties of an existing
   confirmed client ID (if the client wants to update properties of an
   unconfirmed client ID, it MUST NOT set
   EXCHGID4_FLAG_UPD_CONFIRMED_REC_A).  If so, it is RECOMMENDED that
   the client send the update EXCHANGE_ID operation in the same COMPOUND
   as a SEQUENCE so that the EXCHANGE_ID is executed exactly once.
   Whether the client can update the properties of client ID depends on
   the state protection it selected when the client ID was created, and
   the principal and security flavor it uses when sending the
   EXCHANGE_ID request.  The situations described in items 6, 7, 8, or 9
   of the second numbered list of Section 18.35.4 will apply.  Note that
   if the operation succeeds and returns a client ID that is already
   confirmed, the server MUST set the EXCHGID4_FLAG_CONFIRMED_R bit in
   eir_flags.

   If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set in eia_flags, this
   means that the client is trying to establish a new client ID; it is
   attempting to trunk data communication to the server
   (Section 2.10.5); or it is attempting to update properties of an
   unconfirmed client ID.  The situations described in items 1, 2, 3, 4,
   or 5 of the second numbered list of Section 18.35.4 will apply.  Note
   that if the operation succeeds and returns a client ID that was
   previously confirmed, the server MUST set the
   EXCHGID4_FLAG_CONFIRMED_R bit in eir_flags.

   When the EXCHGID4_FLAG_SUPP_MOVED_REFER flag bit is set, the client
   indicates that it is capable of dealing with an NFS4ERR_MOVED error
   as part of a referral sequence.  When this bit is not set, it is
   still legal for the server to perform a referral sequence.  However,
   a server may use the fact that the client is incapable of correctly
   responding to a referral, by avoiding it for that particular client.
   It may, for instance, act as a proxy for that particular file system,
   at some cost in performance, although it is not obligated to do so.
   If the server will potentially perform a referral, it MUST set
   EXCHGID4_FLAG_SUPP_MOVED_REFER in eir_flags.

   When the EXCHGID4_FLAG_SUPP_MOVED_MIGR is set, the client indicates
   that it is capable of dealing with an NFS4ERR_MOVED error as part of
   a file system migration sequence.  When this bit is not set, it is
   still legal for the server to indicate that a file system has moved,
   when this in fact happens.  However, a server may use the fact that
   the client is incapable of correctly responding to a migration in its

Top      Up      ToC       Page 502 
   scheduling of file systems to migrate so as to avoid migration of
   file systems being actively used.  It may also hide actual migrations
   from clients unable to deal with them by acting as a proxy for a
   migrated file system for particular clients, at some cost in
   performance, although it is not obligated to do so.  If the server
   will potentially perform a migration, it MUST set
   EXCHGID4_FLAG_SUPP_MOVED_MIGR in eir_flags.

   When EXCHGID4_FLAG_BIND_PRINC_STATEID is set, the client indicates
   that it wants the server to bind the stateid to the principal.  This
   means that when a principal creates a stateid, it has to be the one
   to use the stateid.  If the server will perform binding, it will
   return EXCHGID4_FLAG_BIND_PRINC_STATEID.  The server MAY return
   EXCHGID4_FLAG_BIND_PRINC_STATEID even if the client does not request
   it.  If an update to the client ID changes the value of
   EXCHGID4_FLAG_BIND_PRINC_STATEID's client ID property, the effect
   applies only to new stateids.  Existing stateids (and all stateids
   with the same "other" field) that were created with stateid to
   principal binding in force will continue to have binding in force.
   Existing stateids (and all stateids with the same "other" field) that
   were created with stateid to principal not in force will continue to
   have binding not in force.

   The EXCHGID4_FLAG_USE_NON_PNFS, EXCHGID4_FLAG_USE_PNFS_MDS, and
   EXCHGID4_FLAG_USE_PNFS_DS bits are described in Section 13.1 and
   convey roles the client ID is to be used for in a pNFS environment.
   The server MUST set one of the acceptable combinations of these bits
   (roles) in eir_flags, as specified in Section 13.1.  Note that the
   same client owner/server owner pair can have multiple roles.
   Multiple roles can be associated with the same client ID or with
   different client IDs.  Thus, if a client sends EXCHANGE_ID from the
   same client owner to the same server owner multiple times, but
   specifies different pNFS roles each time, the server might return
   different client IDs.  Given that different pNFS roles might have
   different client IDs, the client may ask for different properties for
   each role/client ID.

   The spa_how field of the eia_state_protect field specifies how the
   client wants to protect its client, locking, and session states from
   unauthorized changes (Section 2.10.8.3):

   o  SP4_NONE.  The client does not request the NFSv4.1 server to
      enforce state protection.  The NFSv4.1 server MUST NOT enforce
      state protection for the returned client ID.

   o  SP4_MACH_CRED.  If spa_how is SP4_MACH_CRED, then the client MUST
      send the EXCHANGE_ID request with RPCSEC_GSS as the security
      flavor, and with a service of RPC_GSS_SVC_INTEGRITY or

Top      Up      ToC       Page 503 
      RPC_GSS_SVC_PRIVACY.  If SP4_MACH_CRED is specified, then the
      client wants to use an RPCSEC_GSS-based machine credential to
      protect its state.  The server MUST note the principal the
      EXCHANGE_ID operation was sent with, and the GSS mechanism used.
      These notes collectively comprise the machine credential.

      After the client ID is confirmed, as long as the lease associated
      with the client ID is unexpired, a subsequent EXCHANGE_ID
      operation that uses the same eia_clientowner.co_owner as the first
      EXCHANGE_ID MUST also use the same machine credential as the first
      EXCHANGE_ID.  The server returns the same client ID for the
      subsequent EXCHANGE_ID as that returned from the first
      EXCHANGE_ID.

   o  SP4_SSV.  If spa_how is SP4_SSV, then the client MUST send the
      EXCHANGE_ID request with RPCSEC_GSS as the security flavor, and
      with a service of RPC_GSS_SVC_INTEGRITY or RPC_GSS_SVC_PRIVACY.
      If SP4_SSV is specified, then the client wants to use the SSV to
      protect its state.  The server records the credential used in the
      request as the machine credential (as defined above) for the
      eia_clientowner.co_owner.  The CREATE_SESSION operation that
      confirms the client ID MUST use the same machine credential.

   When a client specifies SP4_MACH_CRED or SP4_SSV, it also provides
   two lists of operations (each expressed as a bitmap).  The first list
   is spo_must_enforce and consists of those operations the client MUST
   send (subject to the server confirming the list of operations in the
   result of EXCHANGE_ID) with the machine credential (if SP4_MACH_CRED
   protection is specified) or the SSV-based credential (if SP4_SSV
   protection is used).  The client MUST send the operations with
   RPCSEC_GSS credentials that specify the RPC_GSS_SVC_INTEGRITY or
   RPC_GSS_SVC_PRIVACY security service.  Typically, the first list of
   operations includes EXCHANGE_ID, CREATE_SESSION, DELEGPURGE,
   DESTROY_SESSION, BIND_CONN_TO_SESSION, and DESTROY_CLIENTID.  The
   client SHOULD NOT specify in this list any operations that require a
   filehandle because the server's access policies MAY conflict with the
   client's choice, and thus the client would then be unable to access a
   subset of the server's namespace.

   Note that if SP4_SSV protection is specified, and the client
   indicates that CREATE_SESSION must be protected with SP4_SSV, because
   the SSV cannot exist without a confirmed client ID, the first
   CREATE_SESSION MUST instead be sent using the machine credential, and
   the server MUST accept the machine credential.

   There is a corresponding result, also called spo_must_enforce, of the
   operations for which the server will require SP4_MACH_CRED or SP4_SSV
   protection.  Normally, the server's result equals the client's

Top      Up      ToC       Page 504 
   argument, but the result MAY be different.  If the client requests
   one or more operations in the set { EXCHANGE_ID, CREATE_SESSION,
   DELEGPURGE, DESTROY_SESSION, BIND_CONN_TO_SESSION, DESTROY_CLIENTID
   }, then the result spo_must_enforce MUST include the operations the
   client requested from that set.

   If spo_must_enforce in the results has BIND_CONN_TO_SESSION set, then
   connection binding enforcement is enabled, and the client MUST use
   the machine (if SP4_MACH_CRED protection is used) or SSV (if SP4_SSV
   protection is used) credential on calls to BIND_CONN_TO_SESSION.

   The second list is spo_must_allow and consists of those operations
   the client wants to have the option of sending with the machine
   credential or the SSV-based credential, even if the object the
   operations are performed on is not owned by the machine or SSV
   credential.

   The corresponding result, also called spo_must_allow, consists of the
   operations the server will allow the client to use SP4_SSV or
   SP4_MACH_CRED credentials with.  Normally, the server's result equals
   the client's argument, but the result MAY be different.

   The purpose of spo_must_allow is to allow clients to solve the
   following conundrum.  Suppose the client ID is confirmed with
   EXCHGID4_FLAG_BIND_PRINC_STATEID, and it calls OPEN with the
   RPCSEC_GSS credentials of a normal user.  Now suppose the user's
   credentials expire, and cannot be renewed (e.g., a Kerberos ticket
   granting ticket expires, and the user has logged off and will not be
   acquiring a new ticket granting ticket).  The client will be unable
   to send CLOSE without the user's credentials, which is to say the
   client has to either leave the state on the server or re-send
   EXCHANGE_ID with a new verifier to clear all state, that is, unless
   the client includes CLOSE on the list of operations in spo_must_allow
   and the server agrees.

   The SP4_SSV protection parameters also have:

   ssp_hash_algs:

      This is the set of algorithms the client supports for the purpose
      of computing the digests needed for the internal SSV GSS mechanism
      and for the SET_SSV operation.  Each algorithm is specified as an
      object identifier (OID).  The REQUIRED algorithms for a server are
      id-sha1, id-sha224, id-sha256, id-sha384, and id-sha512 [28].  The
      algorithm the server selects among the set is indicated in
      spi_hash_alg, a field of spr_ssv_prot_info.  The field
      spi_hash_alg is an index into the array ssp_hash_algs.  If the

Top      Up      ToC       Page 505 
      server does not support any of the offered algorithms, it returns
      NFS4ERR_HASH_ALG_UNSUPP.  If ssp_hash_algs is empty, the server
      MUST return NFS4ERR_INVAL.

   ssp_encr_algs:

      This is the set of algorithms the client supports for the purpose
      of providing privacy protection for the internal SSV GSS
      mechanism.  Each algorithm is specified as an OID.  The REQUIRED
      algorithm for a server is id-aes256-CBC.  The RECOMMENDED
      algorithms are id-aes192-CBC and id-aes128-CBC [29].  The selected
      algorithm is returned in spi_encr_alg, an index into
      ssp_encr_algs.  If the server does not support any of the offered
      algorithms, it returns NFS4ERR_ENCR_ALG_UNSUPP.  If ssp_encr_algs
      is empty, the server MUST return NFS4ERR_INVAL.  Note that due to
      previously stated requirements and recommendations on the
      relationships between key length and hash length, some
      combinations of RECOMMENDED and REQUIRED encryption algorithm and
      hash algorithm either SHOULD NOT or MUST NOT be used.  Table 12
      summarizes the illegal and discouraged combinations.

   ssp_window:

      This is the number of SSV versions the client wants the server to
      maintain (i.e., each successful call to SET_SSV produces a new
      version of the SSV).  If ssp_window is zero, the server MUST
      return NFS4ERR_INVAL.  The server responds with spi_window, which
      MUST NOT exceed ssp_window, and MUST be at least one.  Any
      requests on the backchannel or fore channel that are using a
      version of the SSV that is outside the window will fail with an
      ONC RPC authentication error, and the requester will have to retry
      them with the same slot ID and sequence ID.

   ssp_num_gss_handles:

      This is the number of RPCSEC_GSS handles the server should create
      that are based on the GSS SSV mechanism (Section 2.10.9).  It is
      not the total number of RPCSEC_GSS handles for the client ID.
      Indeed, subsequent calls to EXCHANGE_ID will add RPCSEC_GSS
      handles.  The server responds with a list of handles in
      spi_handles.  If the client asks for at least one handle and the
      server cannot create it, the server MUST return an error.  The
      handles in spi_handles are not available for use until the client
      ID is confirmed, which could be immediately if EXCHANGE_ID returns
      EXCHGID4_FLAG_CONFIRMED_R, or upon successful confirmation from
      CREATE_SESSION.

Top      Up      ToC       Page 506 
      While a client ID can span all the connections that are connected
      to a server sharing the same eir_server_owner.so_major_id, the
      RPCSEC_GSS handles returned in spi_handles can only be used on
      connections connected to a server that returns the same the
      eir_server_owner.so_major_id and eir_server_owner.so_minor_id on
      each connection.  It is permissible for the client to set
      ssp_num_gss_handles to zero; the client can create more handles
      with another EXCHANGE_ID call.

      Because each SSV RPCSEC_GSS handle shares a common SSV GSS
      context, there are security considerations specific to this
      situation discussed in Section 2.10.10.

      The seq_window (see Section 5.2.3.1 of RFC2203 [4]) of each
      RPCSEC_GSS handle in spi_handle MUST be the same as the seq_window
      of the RPCSEC_GSS handle used for the credential of the RPC
      request that the EXCHANGE_ID request was sent with.

   +-------------------+----------------------+------------------------+
   | Encryption        | MUST NOT be combined | SHOULD NOT be combined |
   | Algorithm         | with                 | with                   |
   +-------------------+----------------------+------------------------+
   | id-aes128-CBC     |                      | id-sha384, id-sha512   |
   | id-aes192-CBC     | id-sha1              | id-sha512              |
   | id-aes256-CBC     | id-sha1, id-sha224   |                        |
   +-------------------+----------------------+------------------------+

                                 Table 12

   The arguments include an array of up to one element in length called
   eia_client_impl_id.  If eia_client_impl_id is present, it contains
   the information identifying the implementation of the client.
   Similarly, the results include an array of up to one element in
   length called eir_server_impl_id that identifies the implementation
   of the server.  Servers MUST accept a zero-length eia_client_impl_id
   array, and clients MUST accept a zero-length eir_server_impl_id
   array.

   An example use for implementation identifiers would be diagnostic
   software that extracts this information in an attempt to identify
   interoperability problems, performance workload behaviors, or general
   usage statistics.  Since the intent of having access to this
   information is for planning or general diagnosis only, the client and
   server MUST NOT interpret this implementation identity information in
   a way that affects interoperational behavior of the implementation.
   The reason is that if clients and servers did such a thing, they
   might use fewer capabilities of the protocol than the peer can
   support, or the client and server might refuse to interoperate.

Top      Up      ToC       Page 507 
   Because it is possible that some implementations will violate the
   protocol specification and interpret the identity information,
   implementations MUST allow the users of the NFSv4 client and server
   to set the contents of the sent nfs_impl_id structure to any value.

18.35.4.  IMPLEMENTATION

   A server's client record is a 5-tuple:

   1.  co_ownerid

          The client identifier string, from the eia_clientowner
          structure of the EXCHANGE_ID4args structure.

   2.  co_verifier:

          A client-specific value used to indicate incarnations (where a
          client restart represents a new incarnation), from the
          eia_clientowner structure of the EXCHANGE_ID4args structure.

   3.  principal:

          The principal that was defined in the RPC header's credential
          and/or verifier at the time the client record was established.

   4.  client ID:

          The shorthand client identifier, generated by the server and
          returned via the eir_clientid field in the EXCHANGE_ID4resok
          structure.

   5.  confirmed:

          A private field on the server indicating whether or not a
          client record has been confirmed.  A client record is
          confirmed if there has been a successful CREATE_SESSION
          operation to confirm it.  Otherwise, it is unconfirmed.  An
          unconfirmed record is established by an EXCHANGE_ID call.  Any
          unconfirmed record that is not confirmed within a lease period
          SHOULD be removed.

   The following identifiers represent special values for the fields in
   the records.

   ownerid_arg:

      The value of the eia_clientowner.co_ownerid subfield of the
      EXCHANGE_ID4args structure of the current request.

Top      Up      ToC       Page 508 
   verifier_arg:

      The value of the eia_clientowner.co_verifier subfield of the
      EXCHANGE_ID4args structure of the current request.

   old_verifier_arg:

      A value of the eia_clientowner.co_verifier field of a client
      record received in a previous request; this is distinct from
      verifier_arg.

   principal_arg:

      The value of the RPCSEC_GSS principal for the current request.

   old_principal_arg:

      A value of the principal of a client record as defined by the RPC
      header's credential or verifier of a previous request.  This is
      distinct from principal_arg.

   clientid_ret:

      The value of the eir_clientid field the server will return in the
      EXCHANGE_ID4resok structure for the current request.

   old_clientid_ret:

      The value of the eir_clientid field the server returned in the
      EXCHANGE_ID4resok structure for a previous request.  This is
      distinct from clientid_ret.

   confirmed:

      The client ID has been confirmed.

   unconfirmed:

      The client ID has not been confirmed.

   Since EXCHANGE_ID is a non-idempotent operation, we must consider the
   possibility that retries occur as a result of a client restart,
   network partition, malfunctioning router, etc.  Retries are
   identified by the value of the eia_clientowner field of
   EXCHANGE_ID4args, and the method for dealing with them is outlined in
   the scenarios below.

Top      Up      ToC       Page 509 
   The scenarios are described in terms of the client record(s) a server
   has for a given co_ownerid.  Note that if the client ID was created
   specifying SP4_SSV state protection and EXCHANGE_ID as the one of the
   operations in spo_must_allow, then the server MUST authorize
   EXCHANGE_IDs with the SSV principal in addition to the principal that
   created the client ID.

   1.  New Owner ID

          If the server has no client records with
          eia_clientowner.co_ownerid matching ownerid_arg, and
          EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set in the
          EXCHANGE_ID, then a new shorthand client ID (let us call it
          clientid_ret) is generated, and the following unconfirmed
          record is added to the server's state.

          { ownerid_arg, verifier_arg, principal_arg, clientid_ret,
          unconfirmed }

          Subsequently, the server returns clientid_ret.

   2.  Non-Update on Existing Client ID

          If the server has the following confirmed record, and the
          request does not have EXCHGID4_FLAG_UPD_CONFIRMED_REC_A set,
          then the request is the result of a retried request due to a
          faulty router or lost connection, or the client is trying to
          determine if it can perform trunking.

          { ownerid_arg, verifier_arg, principal_arg, clientid_ret,
          confirmed }

          Since the record has been confirmed, the client must have
          received the server's reply from the initial EXCHANGE_ID
          request.  Since the server has a confirmed record, and since
          EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set, with the
          possible exception of eir_server_owner.so_minor_id, the server
          returns the same result it did when the client ID's properties
          were last updated (or if never updated, the result when the
          client ID was created).  The confirmed record is unchanged.

   3.  Client Collision

          If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set, and if the
          server has the following confirmed record, then this request
          is likely the result of a chance collision between the values
          of the eia_clientowner.co_ownerid subfield of EXCHANGE_ID4args
          for two different clients.

Top      Up      ToC       Page 510 
          { ownerid_arg, *, old_principal_arg, old_clientid_ret,
          confirmed }

          If there is currently no state associated with
          old_clientid_ret, or if there is state but the lease has
          expired, then this case is effectively equivalent to the New
          Owner ID case of Paragraph 1.  The confirmed record is
          deleted, the old_clientid_ret and its lock state are deleted,
          a new shorthand client ID is generated, and the following
          unconfirmed record is added to the server's state.

          { ownerid_arg, verifier_arg, principal_arg, clientid_ret,
          unconfirmed }

          Subsequently, the server returns clientid_ret.

          If old_clientid_ret has an unexpired lease with state, then no
          state of old_clientid_ret is changed or deleted.  The server
          returns NFS4ERR_CLID_INUSE to indicate that the client should
          retry with a different value for the
          eia_clientowner.co_ownerid subfield of EXCHANGE_ID4args.  The
          client record is not changed.

   4.  Replacement of Unconfirmed Record

          If the EXCHGID4_FLAG_UPD_CONFIRMED_REC_A flag is not set, and
          the server has the following unconfirmed record, then the
          client is attempting EXCHANGE_ID again on an unconfirmed
          client ID, perhaps due to a retry, a client restart before
          client ID confirmation (i.e., before CREATE_SESSION was
          called), or some other reason.

          { ownerid_arg, *, *, old_clientid_ret, unconfirmed }

          It is possible that the properties of old_clientid_ret are
          different than those specified in the current EXCHANGE_ID.
          Whether or not the properties are being updated, to eliminate
          ambiguity, the server deletes the unconfirmed record,
          generates a new client ID (clientid_ret), and establishes the
          following unconfirmed record:

          { ownerid_arg, verifier_arg, principal_arg, clientid_ret,
          unconfirmed }

Top      Up      ToC       Page 511 
   5.  Client Restart

          If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set, and if the
          server has the following confirmed client record, then this
          request is likely from a previously confirmed client that has
          restarted.

          { ownerid_arg, old_verifier_arg, principal_arg,
          old_clientid_ret, confirmed }

          Since the previous incarnation of the same client will no
          longer be making requests, once the new client ID is confirmed
          by CREATE_SESSION, byte-range locks and share reservations
          should be released immediately rather than forcing the new
          incarnation to wait for the lease time on the previous
          incarnation to expire.  Furthermore, session state should be
          removed since if the client had maintained that information
          across restart, this request would not have been sent.  If the
          server supports neither the CLAIM_DELEGATE_PREV nor
          CLAIM_DELEG_PREV_FH claim types, associated delegations should
          be purged as well; otherwise, delegations are retained and
          recovery proceeds according to Section 10.2.1.

          After processing, clientid_ret is returned to the client and
          this client record is added:

          { ownerid_arg, verifier_arg, principal_arg, clientid_ret,
          unconfirmed }

          The previously described confirmed record continues to exist,
          and thus the same ownerid_arg exists in both a confirmed and
          unconfirmed state at the same time.  The number of states can
          collapse to one once the server receives an applicable
          CREATE_SESSION or EXCHANGE_ID.

          +  If the server subsequently receives a successful
             CREATE_SESSION that confirms clientid_ret, then the server
             atomically destroys the confirmed record and makes the
             unconfirmed record confirmed as described in
             Section 18.36.4.

          +  If the server instead subsequently receives an EXCHANGE_ID
             with the client owner equal to ownerid_arg, one strategy is
             to simply delete the unconfirmed record, and process the
             EXCHANGE_ID as described in the entirety of
             Section 18.35.4.

Top      Up      ToC       Page 512 
   6.  Update

          If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server
          has the following confirmed record, then this request is an
          attempt at an update.

          { ownerid_arg, verifier_arg, principal_arg, clientid_ret,
          confirmed }

          Since the record has been confirmed, the client must have
          received the server's reply from the initial EXCHANGE_ID
          request.  The server allows the update, and the client record
          is left intact.

   7.  Update but No Confirmed Record

          If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server
          has no confirmed record corresponding ownerid_arg, then the
          server returns NFS4ERR_NOENT and leaves any unconfirmed record
          intact.

   8.  Update but Wrong Verifier

          If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server
          has the following confirmed record, then this request is an
          illegal attempt at an update, perhaps because of a retry from
          a previous client incarnation.

          { ownerid_arg, old_verifier_arg, *, clientid_ret, confirmed }

          The server returns NFS4ERR_NOT_SAME and leaves the client
          record intact.

   9.  Update but Wrong Principal

          If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server
          has the following confirmed record, then this request is an
          illegal attempt at an update by an unauthorized principal.

          { ownerid_arg, verifier_arg, old_principal_arg, clientid_ret,
          confirmed }

          The server returns NFS4ERR_PERM and leaves the client record
          intact.

Top      Up      ToC       Page 513 
18.36.  Operation 43: CREATE_SESSION - Create New Session and Confirm
        Client ID

18.36.1.  ARGUMENT

   struct channel_attrs4 {
           count4                  ca_headerpadsize;
           count4                  ca_maxrequestsize;
           count4                  ca_maxresponsesize;
           count4                  ca_maxresponsesize_cached;
           count4                  ca_maxoperations;
           count4                  ca_maxrequests;
           uint32_t                ca_rdma_ird<1>;
   };

   const CREATE_SESSION4_FLAG_PERSIST              = 0x00000001;
   const CREATE_SESSION4_FLAG_CONN_BACK_CHAN       = 0x00000002;
   const CREATE_SESSION4_FLAG_CONN_RDMA            = 0x00000004;

   struct CREATE_SESSION4args {
           clientid4               csa_clientid;
           sequenceid4             csa_sequence;

           uint32_t                csa_flags;

           channel_attrs4          csa_fore_chan_attrs;
           channel_attrs4          csa_back_chan_attrs;

           uint32_t                csa_cb_program;
           callback_sec_parms4     csa_sec_parms<>;
   };

18.36.2.  RESULT

   struct CREATE_SESSION4resok {
           sessionid4              csr_sessionid;
           sequenceid4             csr_sequence;

           uint32_t                csr_flags;

           channel_attrs4          csr_fore_chan_attrs;
           channel_attrs4          csr_back_chan_attrs;
   };

Top      Up      ToC       Page 514 
   union CREATE_SESSION4res switch (nfsstat4 csr_status) {
   case NFS4_OK:
           CREATE_SESSION4resok    csr_resok4;
   default:
           void;
   };

18.36.3.  DESCRIPTION

   This operation is used by the client to create new session objects on
   the server.

   CREATE_SESSION can be sent with or without a preceding SEQUENCE
   operation in the same COMPOUND procedure.  If CREATE_SESSION is sent
   with a preceding SEQUENCE operation, any session created by
   CREATE_SESSION has no direct relation to the session specified in the
   SEQUENCE operation, although the two sessions might be associated
   with the same client ID.  If CREATE_SESSION is sent without a
   preceding SEQUENCE, then it MUST be the only operation in the
   COMPOUND procedure's request.  If it is not, the server MUST return
   NFS4ERR_NOT_ONLY_OP.

   In addition to creating a session, CREATE_SESSION has the following
   effects:

   o  The first session created with a new client ID serves to confirm
      the creation of that client's state on the server.  The server
      returns the parameter values for the new session.

   o  The connection CREATE_SESSION that is sent over is associated with
      the session's fore channel.

   The arguments and results of CREATE_SESSION are described as follows:

   csa_clientid:

      This is the client ID with which the new session will be
      associated.  The corresponding result is csr_sessionid, the
      session ID of the new session.

   csa_sequence:

      Each client ID serializes CREATE_SESSION via a per-client ID
      sequence number (see Section 18.36.4).  The corresponding result
      is csr_sequence, which MUST be equal to csa_sequence.

Top      Up      ToC       Page 515 
   In the next three arguments, the client offers a value that is to be
   a property of the session.  Except where stated otherwise, it is
   RECOMMENDED that the server accept the value.  If it is not
   acceptable, the server MAY use a different value.  Regardless, the
   server MUST return the value the session will use (which will be
   either what the client offered, or what the server is insisting on)
   to the client.

   csa_flags:

      The csa_flags field contains a list of the following flag bits:

      CREATE_SESSION4_FLAG_PERSIST:

         If CREATE_SESSION4_FLAG_PERSIST is set, the client wants the
         server to provide a persistent reply cache.  For sessions in
         which only idempotent operations will be used (e.g., a read-
         only session), clients SHOULD NOT set
         CREATE_SESSION4_FLAG_PERSIST.  If the server does not or cannot
         provide a persistent reply cache, the server MUST NOT set
         CREATE_SESSION4_FLAG_PERSIST in the field csr_flags.

         If the server is a pNFS metadata server, for reasons described
         in Section 12.5.2 it SHOULD support
         CREATE_SESSION4_FLAG_PERSIST if it supports the layout_hint
         (Section 5.12.4) attribute.

      CREATE_SESSION4_FLAG_CONN_BACK_CHAN:

         If CREATE_SESSION4_FLAG_CONN_BACK_CHAN is set in csa_flags, the
         client is requesting that the connection over which the
         CREATE_SESSION operation arrived be associated with the
         session's backchannel in addition to its fore channel.  If the
         server agrees, it sets CREATE_SESSION4_FLAG_CONN_BACK_CHAN in
         the result field csr_flags.  If
         CREATE_SESSION4_FLAG_CONN_BACK_CHAN is not set in csa_flags,
         then CREATE_SESSION4_FLAG_CONN_BACK_CHAN MUST NOT be set in
         csr_flags.

      CREATE_SESSION4_FLAG_CONN_RDMA:

         If CREATE_SESSION4_FLAG_CONN_RDMA is set in csa_flags, and if
         the connection over which the CREATE_SESSION operation arrived
         is currently in non-RDMA mode but has the capability to operate
         in RDMA mode, then the client is requesting that the server
         "step up" to RDMA mode on the connection.  If the server
         agrees, it sets CREATE_SESSION4_FLAG_CONN_RDMA in the result
         field csr_flags.  If CREATE_SESSION4_FLAG_CONN_RDMA is not set

Top      Up      ToC       Page 516 
         in csa_flags, then CREATE_SESSION4_FLAG_CONN_RDMA MUST NOT be
         set in csr_flags.  Note that once the server agrees to step up,
         it and the client MUST exchange all future traffic on the
         connection with RPC RDMA framing and not Record Marking ([8]).

   csa_fore_chan_attrs, csa_fore_chan_attrs:

      The csa_fore_chan_attrs and csa_back_chan_attrs fields apply to
      attributes of the fore channel (which conveys requests originating
      from the client to the server), and the backchannel (the channel
      that conveys callback requests originating from the server to the
      client), respectively.  The results are in corresponding
      structures called csr_fore_chan_attrs and csr_back_chan_attrs.
      The results establish attributes for each channel, and on all
      subsequent use of each channel of the session.  Each structure has
      the following fields:

      ca_headerpadsize:

         The maximum amount of padding the requester is willing to apply
         to ensure that write payloads are aligned on some boundary at
         the replier.  For each channel, the server

         +  will reply in ca_headerpadsize with its preferred value, or
            zero if padding is not in use, and

         +  MAY decrease this value but MUST NOT increase it.

      ca_maxrequestsize:

         The maximum size of a COMPOUND or CB_COMPOUND request that will
         be sent.  This size represents the XDR encoded size of the
         request, including the RPC headers (including security flavor
         credentials and verifiers) but excludes any RPC transport
         framing headers.  Imagine a request coming over a non-RDMA
         TCP/IP connection, and that it has a single Record Marking
         header preceding it.  The maximum allowable count encoded in
         the header will be ca_maxrequestsize.  If a requester sends a
         request that exceeds ca_maxrequestsize, the error
         NFS4ERR_REQ_TOO_BIG will be returned per the description in
         Section 2.10.6.4.  For each channel, the server MAY decrease
         this value but MUST NOT increase it.

      ca_maxresponsesize:

         The maximum size of a COMPOUND or CB_COMPOUND reply that the
         requester will accept from the replier including RPC headers
         (see the ca_maxrequestsize definition).  For each channel, the

Top      Up      ToC       Page 517 
         server MAY decrease this value, but MUST NOT increase it.
         However, if the client selects a value for ca_maxresponsesize
         such that a replier on a channel could never send a response,
         the server SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION
         reply.  After the session is created, if a requester sends a
         request for which the size of the reply would exceed this
         value, the replier will return NFS4ERR_REP_TOO_BIG, per the
         description in Section 2.10.6.4.

      ca_maxresponsesize_cached:

         Like ca_maxresponsesize, but the maximum size of a reply that
         will be stored in the reply cache (Section 2.10.6.1).  For each
         channel, the server MAY decrease this value, but MUST NOT
         increase it.  If, in the reply to CREATE_SESSION, the value of
         ca_maxresponsesize_cached of a channel is less than the value
         of ca_maxresponsesize of the same channel, then this is an
         indication to the requester that it needs to be selective about
         which replies it directs the replier to cache; for example,
         large replies from nonidempotent operations (e.g., COMPOUND
         requests with a READ operation) should not be cached.  The
         requester decides which replies to cache via an argument to the
         SEQUENCE (the sa_cachethis field, see Section 18.46) or
         CB_SEQUENCE (the csa_cachethis field, see Section 20.9)
         operations.  After the session is created, if a requester sends
         a request for which the size of the reply would exceed
         ca_maxresponsesize_cached, the replier will return
         NFS4ERR_REP_TOO_BIG_TO_CACHE, per the description in
         Section 2.10.6.4.

      ca_maxoperations:

         The maximum number of operations the replier will accept in a
         COMPOUND or CB_COMPOUND.  For the backchannel, the server MUST
         NOT change the value the client offers.  For the fore channel,
         the server MAY change the requested value.  After the session
         is created, if a requester sends a COMPOUND or CB_COMPOUND with
         more operations than ca_maxoperations, the replier MUST return
         NFS4ERR_TOO_MANY_OPS.

      ca_maxrequests:

         The maximum number of concurrent COMPOUND or CB_COMPOUND
         requests the requester will send on the session.  Subsequent
         requests will each be assigned a slot identifier by the
         requester within the range zero to ca_maxrequests - 1

Top      Up      ToC       Page 518 
         inclusive.  For the backchannel, the server MUST NOT change the
         value the client offers.  For the fore channel, the server MAY
         change the requested value.

      ca_rdma_ird:

         This array has a maximum of one element.  If this array has one
         element, then the element contains the inbound RDMA read queue
         depth (IRD).  For each channel, the server MAY decrease this
         value, but MUST NOT increase it.

   csa_cb_program

      This is the ONC RPC program number the server MUST use in any
      callbacks sent through the backchannel to the client.  The server
      MUST specify an ONC RPC program number equal to csa_cb_program and
      an ONC RPC version number equal to 4 in callbacks sent to the
      client.  If a CB_COMPOUND is sent to the client, the server MUST
      use a minor version number of 1.  There is no corresponding
      result.

   csa_sec_parms

      The field csa_sec_parms is an array of acceptable security
      credentials the server can use on the session's backchannel.
      Three security flavors are supported: AUTH_NONE, AUTH_SYS, and
      RPCSEC_GSS.  If AUTH_NONE is specified for a credential, then this
      says the client is authorizing the server to use AUTH_NONE on all
      callbacks for the session.  If AUTH_SYS is specified, then the
      client is authorizing the server to use AUTH_SYS on all callbacks,
      using the credential specified cbsp_sys_cred.  If RPCSEC_GSS is
      specified, then the server is allowed to use the RPCSEC_GSS
      context specified in cbsp_gss_parms as the RPCSEC_GSS context in
      the credential of the RPC header of callbacks to the client.
      There is no corresponding result.

      The RPCSEC_GSS context for the backchannel is specified via a pair
      of values of data type gsshandle4_t.  The data type gsshandle4_t
      represents an RPCSEC_GSS handle, and is precisely the same as the
      data type of the "handle" field of the rpc_gss_init_res data type
      defined in Section 5.2.3.1, "Context Creation Response -
      Successful Acceptance", of [4].

      The first RPCSEC_GSS handle, gcbp_handle_from_server, is the fore
      handle the server returned to the client (either in the handle
      field of data type rpc_gss_init_res or as one of the elements of
      the spi_handles field returned in the reply to EXCHANGE_ID) when
      the RPCSEC_GSS context was created on the server.  The second

Top      Up      ToC       Page 519 
      handle, gcbp_handle_from_client, is the back handle to which the
      client will map the RPCSEC_GSS context.  The server can
      immediately use the value of gcbp_handle_from_client in the
      RPCSEC_GSS credential in callback RPCs.  That is, the value in
      gcbp_handle_from_client can be used as the value of the field
      "handle" in data type rpc_gss_cred_t (see Section 5, "Elements of
      the RPCSEC_GSS Security Protocol", of [4]) in callback RPCs.  The
      server MUST use the RPCSEC_GSS security service specified in
      gcbp_service, i.e., it MUST set the "service" field of the
      rpc_gss_cred_t data type in RPCSEC_GSS credential to the value of
      gcbp_service (see Section 5.3.1, "RPC Request Header", of [4]).

      If the RPCSEC_GSS handle identified by gcbp_handle_from_server
      does not exist on the server, the server will return
      NFS4ERR_NOENT.

      Within each element of csa_sec_parms, the fore and back RPCSEC_GSS
      contexts MUST share the same GSS context and MUST have the same
      seq_window (see Section 5.2.3.1 of RFC2203 [4]).  The fore and
      back RPCSEC_GSS context state are independent of each other as far
      as the RPCSEC_GSS sequence number (see the seq_num field in the
      rpc_gss_cred_t data type of Sections 5 and 5.3.1 of [4]).

      If an RPCSEC_GSS handle is using the SSV context (see
      Section 2.10.9), then because each SSV RPCSEC_GSS handle shares a
      common SSV GSS context, there are security considerations specific
      to this situation discussed in Section 2.10.10.

   Once the session is created, the first SEQUENCE or CB_SEQUENCE
   received on a slot MUST have a sequence ID equal to 1; if not, the
   replier MUST return NFS4ERR_SEQ_MISORDERED.

18.36.4.  IMPLEMENTATION

   To describe a possible implementation, the same notation for client
   records introduced in the description of EXCHANGE_ID is used with the
   following addition:

      clientid_arg: The value of the csa_clientid field of the
      CREATE_SESSION4args structure of the current request.

   Since CREATE_SESSION is a non-idempotent operation, we need to
   consider the possibility that retries may occur as a result of a
   client restart, network partition, malfunctioning router, etc.  For
   each client ID created by EXCHANGE_ID, the server maintains a
   separate reply cache (called the CREATE_SESSION reply cache) similar
   to the session reply cache used for SEQUENCE operations, with two
   distinctions.

Top      Up      ToC       Page 520 
   o  First, this is a reply cache just for detecting and processing
      CREATE_SESSION requests for a given client ID.

   o  Second, the size of the client ID reply cache is of one slot (and
      as a result, the CREATE_SESSION request does not carry a slot
      number).  This means that at most one CREATE_SESSION request for a
      given client ID can be outstanding.

   As previously stated, CREATE_SESSION can be sent with or without a
   preceding SEQUENCE operation.  Even if a SEQUENCE precedes
   CREATE_SESSION, the server MUST maintain the CREATE_SESSION reply
   cache, which is separate from the reply cache for the session
   associated with a SEQUENCE.  If CREATE_SESSION was originally sent by
   itself, the client MAY send a retry of the CREATE_SESSION operation
   within a COMPOUND preceded by a SEQUENCE.  If CREATE_SESSION was
   originally sent in a COMPOUND that started with a SEQUENCE, then the
   client SHOULD send a retry in a COMPOUND that starts with a SEQUENCE
   that has the same session ID as the SEQUENCE of the original request.
   However, the client MAY send a retry in a COMPOUND that either has no
   preceding SEQUENCE, or has a preceding SEQUENCE that refers to a
   different session than the original CREATE_SESSION.  This might be
   necessary if the client sends a CREATE_SESSION in a COMPOUND preceded
   by a SEQUENCE with session ID X, and session X no longer exists.
   Regardless, any retry of CREATE_SESSION, with or without a preceding
   SEQUENCE, MUST use the same value of csa_sequence as the original.

   After the client received a reply to an EXCHANGE_ID operation that
   contains a new, unconfirmed client ID, the server expects the client
   to follow with a CREATE_SESSION operation to confirm the client ID.
   The server expects value of csa_sequenceid in the arguments to that
   CREATE_SESSION to be to equal the value of the field eir_sequenceid
   that was returned in results of the EXCHANGE_ID that returned the
   unconfirmed client ID.  Before the server replies to that EXCHANGE_ID
   operation, it initializes the client ID slot to be equal to
   eir_sequenceid - 1 (accounting for underflow), and records a
   contrived CREATE_SESSION result with a "cached" result of
   NFS4ERR_SEQ_MISORDERED.  With the client ID slot thus initialized,
   the processing of the CREATE_SESSION operation is divided into four
   phases:

   1.  Client record look up.  The server looks up the client ID in its
       client record table.  If the server contains no records with
       client ID equal to clientid_arg, then most likely the client's
       state has been purged during a period of inactivity, possibly due
       to a loss of connectivity.  NFS4ERR_STALE_CLIENTID is returned,
       and no changes are made to any client records on the server.
       Otherwise, the server goes to phase 2.

Top      Up      ToC       Page 521 
   2.  Sequence ID processing.  If csa_sequenceid is equal to the
       sequence ID in the client ID's slot, then this is a replay of the
       previous CREATE_SESSION request, and the server returns the
       cached result.  If csa_sequenceid is not equal to the sequence ID
       in the slot, and is more than one greater (accounting for
       wraparound), then the server returns the error
       NFS4ERR_SEQ_MISORDERED, and does not change the slot.  If
       csa_sequenceid is equal to the slot's sequence ID + 1 (accounting
       for wraparound), then the slot's sequence ID is set to
       csa_sequenceid, and the CREATE_SESSION processing goes to the
       next phase.  A subsequent new CREATE_SESSION call over the same
       client ID MUST use a csa_sequenceid that is one greater than the
       sequence ID in the slot.

   3.  Client ID confirmation.  If this would be the first session for
       the client ID, the CREATE_SESSION operation serves to confirm the
       client ID.  Otherwise, the client ID confirmation phase is
       skipped and only the session creation phase occurs.  Any case in
       which there is more than one record with identical values for
       client ID represents a server implementation error.  Operation in
       the potential valid cases is summarized as follows.

       *  Successful Confirmation

             If the server has the following unconfirmed record, then
             this is the expected confirmation of an unconfirmed record.

             { ownerid, verifier, principal_arg, clientid_arg,
             unconfirmed }

             As noted in Section 18.35.4, the server might also have the
             following confirmed record.

             { ownerid, old_verifier, principal_arg, old_clientid,
             confirmed }

             The server schedules the replacement of both records with:

             { ownerid, verifier, principal_arg, clientid_arg, confirmed
             }

             The processing of CREATE_SESSION continues on to session
             creation.  Once the session is successfully created, the
             scheduled client record replacement is committed.  If the
             session is not successfully created, then no changes are
             made to any client records on the server.

Top      Up      ToC       Page 522 
       *  Unsuccessful Confirmation

             If the server has the following record, then the client has
             changed principals after the previous EXCHANGE_ID request,
             or there has been a chance collision between shorthand
             client identifiers.

             { *, *, old_principal_arg, clientid_arg, * }

             Neither of these cases is permissible.  Processing stops
             and NFS4ERR_CLID_INUSE is returned to the client.  No
             changes are made to any client records on the server.

   4.  Session creation.  The server confirmed the client ID, either in
       this CREATE_SESSION operation, or a previous CREATE_SESSION
       operation.  The server examines the remaining fields of the
       arguments.

       The server creates the session by recording the parameter values
       used (including whether the CREATE_SESSION4_FLAG_PERSIST flag is
       set and has been accepted by the server) and allocating space for
       the session reply cache (if there is not enough space, the server
       returns NFS4ERR_NOSPC).  For each slot in the reply cache, the
       server sets the sequence ID to zero, and records an entry
       containing a COMPOUND reply with zero operations and the error
       NFS4ERR_SEQ_MISORDERED.  This way, if the first SEQUENCE request
       sent has a sequence ID equal to zero, the server can simply
       return what is in the reply cache: NFS4ERR_SEQ_MISORDERED.  The
       client initializes its reply cache for receiving callbacks in the
       same way, and similarly, the first CB_SEQUENCE operation on a
       slot after session creation MUST have a sequence ID of one.

       If the session state is created successfully, the server
       associates the session with the client ID provided by the client.

       When a request that had CREATE_SESSION4_FLAG_CONN_RDMA set needs
       to be retried, the retry MUST be done on a new connection that is
       in non-RDMA mode.  If properties of the new connection are
       different enough that the arguments to CREATE_SESSION need to
       change, then a non-retry MUST be sent.  The server will
       eventually dispose of any session that was created on the
       original connection.

   On the backchannel, the client and server might wish to have many
   slots, in some cases perhaps more that the fore channel, in order to
   deal with the situations where the network link has high latency and

Top      Up      ToC       Page 523 
   is the primary bottleneck for response to recalls.  If so, and if the
   client provides too few slots to the backchannel, the server might
   limit the number of recallable objects it gives to the client.

   Implementing RPCSEC_GSS callback support requires changes to both the
   client and server implementations of RPCSEC_GSS.  One possible set of
   changes includes:

   o  Adding a data structure that wraps the GSS-API context with a
      reference count.

   o  New functions to increment and decrement the reference count.  If
      the reference count is decremented to zero, the wrapper data
      structure and the GSS-API context it refers to would be freed.

   o  Change RPCSEC_GSS to create the wrapper data structure upon
      receiving GSS-API context from gss_accept_sec_context() and
      gss_init_sec_context().  The reference count would be initialized
      to 1.

   o  Adding a function to map an existing RPCSEC_GSS handle to a
      pointer to the wrapper data structure.  The reference count would
      be incremented.

   o  Adding a function to create a new RPCSEC_GSS handle from a pointer
      to the wrapper data structure.  The reference count would be
      incremented.

   o  Replacing calls from RPCSEC_GSS that free GSS-API contexts, with
      calls to decrement the reference count on the wrapper data
      structure.

18.37.  Operation 44: DESTROY_SESSION - Destroy a Session

18.37.1.  ARGUMENT

   struct DESTROY_SESSION4args {
           sessionid4      dsa_sessionid;
   };

18.37.2.  RESULT

   struct DESTROY_SESSION4res {
           nfsstat4        dsr_status;
   };

Top      Up      ToC       Page 524 
18.37.3.  DESCRIPTION

   The DESTROY_SESSION operation closes the session and discards the
   session's reply cache, if any.  Any remaining connections associated
   with the session are immediately disassociated.  If the connection
   has no remaining associated sessions, the connection MAY be closed by
   the server.  Locks, delegations, layouts, wants, and the lease, which
   are all tied to the client ID, are not affected by DESTROY_SESSION.

   DESTROY_SESSION MUST be invoked on a connection that is associated
   with the session being destroyed.  In addition, if SP4_MACH_CRED
   state protection was specified when the client ID was created, the
   RPCSEC_GSS principal that created the session MUST be the one that
   destroys the session, using RPCSEC_GSS privacy or integrity.  If
   SP4_SSV state protection was specified when the client ID was
   created, RPCSEC_GSS using the SSV mechanism (Section 2.10.9) MUST be
   used, with integrity or privacy.

   If the COMPOUND request starts with SEQUENCE, and if the sessionids
   specified in SEQUENCE and DESTROY_SESSION are the same, then

   o  DESTROY_SESSION MUST be the final operation in the COMPOUND
      request.

   o  It is advisable to avoid placing DESTROY_SESSION in a COMPOUND
      request with other state-modifying operations, because the
      DESTROY_SESSION will destroy the reply cache.

   o  Because the session and its reply cache are destroyed, a client
      that retries the request may receive an error in reply to the
      retry, even though the original request was successful.

   If the COMPOUND request starts with SEQUENCE, and if the sessionids
   specified in SEQUENCE and DESTROY_SESSION are different, then
   DESTROY_SESSION can appear in any position of the COMPOUND request
   (except for the first position).  The two sessionids can belong to
   different client IDs.

   If the COMPOUND request does not start with SEQUENCE, and if
   DESTROY_SESSION is not the sole operation, then server MUST return
   NFS4ERR_NOT_ONLY_OP.

   If there is a backchannel on the session and the server has
   outstanding CB_COMPOUND operations for the session which have not
   been replied to, then the server MAY refuse to destroy the session
   and return an error.  If so, then in the event the backchannel is
   down, the server SHOULD return NFS4ERR_CB_PATH_DOWN to inform the
   client that the backchannel needs to be repaired before the server

Top      Up      ToC       Page 525 
   will allow the session to be destroyed.  Otherwise, the error
   CB_BACK_CHAN_BUSY SHOULD be returned to indicate that there are
   CB_COMPOUNDs that need to be replied to.  The client SHOULD reply to
   all outstanding CB_COMPOUNDs before re-sending DESTROY_SESSION.

18.38.  Operation 45: FREE_STATEID - Free Stateid with No Locks

18.38.1.  ARGUMENT

   struct FREE_STATEID4args {
           stateid4        fsa_stateid;
   };

18.38.2.  RESULT

   struct FREE_STATEID4res {
           nfsstat4        fsr_status;
   };

18.38.3.  DESCRIPTION

   The FREE_STATEID operation is used to free a stateid that no longer
   has any associated locks (including opens, byte-range locks,
   delegations, and layouts).  This may be because of client LOCKU
   operations or because of server revocation.  If there are valid locks
   (of any kind) associated with the stateid in question, the error
   NFS4ERR_LOCKS_HELD will be returned, and the associated stateid will
   not be freed.

   When a stateid is freed that had been associated with revoked locks,
   by sending the FREE_STATEID operation, the client acknowledges the
   loss of those locks.  This allows the server, once all such revoked
   state is acknowledged, to allow that client again to reclaim locks,
   without encountering the edge conditions discussed in Section 8.4.2.

   Once a successful FREE_STATEID is done for a given stateid, any
   subsequent use of that stateid will result in an NFS4ERR_BAD_STATEID
   error.


Next RFC Part