implement backchannel security negotation
Subsystems (3)
This is an incomplete implementation of the (mandatory) NFSv4.1 backchannel security negotation, only enough to handle auth_unix and auth_null; auth_gss will need more work.
--b.
PATCH 1/5 nfsd4: clean up callback security parsing
From: "J. Bruce Fields" <[email protected]>
Move the callback parsing into a separate function.
--- fs/nfsd/nfs4xdr.c | 118 ++++++++++++++++++++++++++++------------------------- fs/nfsd/state.h | 9 +++- 2 files changed, 70 insertions(+), 57 deletions(-)
fs/nfsd/nfs4xdr.c +63 -55
@@ -422,6 +422,67 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *accessDECODE_TAIL ; } +static __be32 nfsd4_decode_cb_sec (struct nfsd4_compoundargs *argp,struct nfsd4_cb_sec *cbs) +{ +DECODE_HEAD ; +u32 dummy; +char *machine_name; +int i; +int nr_secflavs; + +/* callback_sec_params4 */ +READ_BUF (4 ); +READ32 (nr_secflavs); +for (i =0 ; i < nr_secflavs; ++i) { +READ_BUF (4 ); +READ32 (dummy); +switch (dummy) { +case RPC_AUTH_NULL : +/* Nothing to read */ +break ; +case RPC_AUTH_UNIX : +READ_BUF (8 ); +/* stamp */ +READ32 (dummy); + +/* machine name */ +READ32 (dummy); +READ_BUF (dummy); +SAVEMEM (machine_name, dummy); + +/* uid, gid */ +READ_BUF (8 ); +READ32 (cbs->uid); +READ32 (cbs->gid); + +/* more gids */ +READ_BUF (4 ); +READ32 (dummy); +READ_BUF (dummy *4 ); +break ; +case RPC_AUTH_GSS : +dprintk ("RPC_AUTH_GSS callback secflavor " +"not supported!\n" ); +READ_BUF (8 ); +/* gcbp_service */ +READ32 (dummy); +/* gcbp_handle_from_server */ +READ32 (dummy); +READ_BUF (dummy); + p +=XDR_QUADLEN (dummy); +/* gcbp_handle_from_client */ +READ_BUF (4 ); +READ32 (dummy); +READ_BUF (dummy); +break ; +default : +dprintk ("Illegal callback secflavor\n" ); +return nfserr_inval; + } + } +DECODE_TAIL ; +} +static __be32 nfsd4_decode_bind_conn_to_session (struct nfsd4_compoundargs *argp,struct nfsd4_bind_conn_to_session *bcts) {DECODE_HEAD ;
@@ -1237,11 +1298,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, struct nfsd4_create_session *sess) {DECODE_HEAD ; -u32 dummy; -char *machine_name; -int i; -int nr_secflavs;READ_BUF (16 );COPYMEM (&sess->clientid,8 );
@@ -1282,58 +1339,9 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, goto xdr_error; } -READ_BUF (8 ); +READ_BUF (4 );READ32 (sess->callback_prog); - -/* callback_sec_params4 */ -READ32 (nr_secflavs); -for (i =0 ; i < nr_secflavs; ++i) { -READ_BUF (4 ); -READ32 (dummy); -switch (dummy) { -case RPC_AUTH_NULL : -/* Nothing to read */ -break ; -case RPC_AUTH_UNIX : -READ_BUF (8 ); -/* stamp */ -READ32 (dummy); - -/* machine name */ -READ32 (dummy); -READ_BUF (dummy); -SAVEMEM (machine_name, dummy); - -/* uid, gid */ -READ_BUF (8 ); -READ32 (sess->uid); -READ32 (sess->gid); - -/* more gids */ -READ_BUF (4 ); -READ32 (dummy); -READ_BUF (dummy *4 ); -break ; -case RPC_AUTH_GSS : -dprintk ("RPC_AUTH_GSS callback secflavor " -"not supported!\n" ); -READ_BUF (8 ); -/* gcbp_service */ -READ32 (dummy); -/* gcbp_handle_from_server */ -READ32 (dummy); -READ_BUF (dummy); - p +=XDR_QUADLEN (dummy); -/* gcbp_handle_from_client */ -READ_BUF (4 ); -READ32 (dummy); -READ_BUF (dummy); -break ; -default : -dprintk ("Illegal callback secflavor\n" ); -return nfserr_inval; - } - } +nfsd4_decode_cb_sec (argp, &sess->cb_sec);DECODE_TAIL ; }
fs/nfsd/state.h +7 -2
@@ -150,6 +150,11 @@ struct nfsd4_channel_attrs {u32 rdma_attrs; }; +struct nfsd4_cb_sec { +u32 uid; +u32 gid; +}; +struct nfsd4_create_session {clientid_t clientid;struct nfs4_sessionid sessionid;
@@ -158,8 +163,7 @@ struct nfsd4_create_session {struct nfsd4_channel_attrs fore_channel;struct nfsd4_channel_attrs back_channel;u32 callback_prog; -u32 uid; -u32 gid; +struct nfsd4_cb_sec cb_sec; };struct nfsd4_bind_conn_to_session {
@@ -192,6 +196,7 @@ struct nfsd4_session {struct nfs4_sessionid se_sessionid;struct nfsd4_channel_attrs se_fchannel;struct nfsd4_channel_attrs se_bchannel; +struct nfsd4_cb_sec se_cb_sec;struct list_head se_conns;u32 se_cb_prog;u32 se_cb_seq_nr;
Signature · 1 line
1.7.9.5
PATCH 2/5 nfsd4: use callback security parameters in create_session
In reply to J. Bruce FieldsFrom: "J. Bruce Fields" <[email protected]>
We're currently ignoring the callback security parameters specified in create_session, and just assuming the client wants auth_sys, because that's all the current linux client happens to care about. But this could cause us callbacks to fail to a client that wanted something different.
For now, all we're doing is no longer ignoring the uid and gid passed in the auth_sys case. Further patches will add support for auth_null and gss (and possibly use more of the auth_sys information; the spec wants us to use exactly the credential we're passed, though it's hard to imagine why a client would care).
--- fs/nfsd/nfs4callback.c | 49 ++++++++++++++++++++++++++++++++++-------------- fs/nfsd/nfs4state.c | 1 + fs/nfsd/state.h | 1 + 3 files changed, 37 insertions(+), 14 deletions(-)
fs/nfsd/nfs4callback.c +35 -14
@@ -630,6 +630,31 @@ static int max_cb_time(void)return max (nfsd4_lease/10 , (time_t )1 ) *HZ ; } +static struct rpc_cred *callback_cred; + +int set_callback_cred (void ) +{ +if (callback_cred) +return 0 ; + callback_cred =rpc_lookup_machine_cred ("nfs" ); +if (!callback_cred) +return -ENOMEM ; +return 0 ; +} + +struct rpc_cred *get_backchannel_cred (struct nfs4_client *clp,struct rpc_clnt *client,struct nfsd4_session *ses) +{ +if (clp->cl_minorversion ==0 ) { +return get_rpccred (callback_cred); + }else { +struct rpc_auth *auth = client->cl_auth; +struct auth_cred acred = {}; + + acred.uid = ses->se_cb_sec.uid; + acred.gid = ses->se_cb_sec.gid; +return auth->au_ops->lookup_cred (client->cl_auth, &acred,0 ); + } +}static int setup_callback_client (struct nfs4_client *clp,struct nfs4_cb_conn *conn,struct nfsd4_session *ses) {
@@ -648,6 +673,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), };struct rpc_clnt *client; +struct rpc_cred *cred;if (clp->cl_minorversion ==0 ) { if (!clp->cl_cred.cr_principal &&
@@ -675,7 +701,13 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c PTR_ERR(client));return PTR_ERR (client); } + cred =get_backchannel_cred (clp, client, ses); +if (IS_ERR (cred)) { +rpc_shutdown_client (client); +return PTR_ERR (cred); + } clp->cl_cb_client = client; + clp->cl_cb_cred = cred;return 0 ; }
@@ -714,18 +746,6 @@ static const struct rpc_call_ops nfsd4_cb_probe_ops = { .rpc_call_done = nfsd4_cb_probe_done, }; -static struct rpc_cred *callback_cred; - -int set_callback_cred (void ) -{ -if (callback_cred) -return 0 ; - callback_cred =rpc_lookup_machine_cred ("nfs" ); -if (!callback_cred) -return -ENOMEM ; -return 0 ; -} -static struct workqueue_struct *callback_wq;static void run_nfsd4_cb (struct nfsd4_callback *cb)
@@ -743,7 +763,6 @@ static void do_probe_callback(struct nfs4_client *clp) cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL ]; cb->cb_msg.rpc_argp =NULL ; cb->cb_msg.rpc_resp =NULL ; - cb->cb_msg.rpc_cred = callback_cred; cb->cb_ops = &nfsd4_cb_probe_ops;
@@ -962,6 +981,8 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)if (clp->cl_cb_client) {rpc_shutdown_client (clp->cl_cb_client); clp->cl_cb_client =NULL ; +put_rpccred (clp->cl_cb_cred); + clp->cl_cb_cred =NULL ; }if (clp->cl_cb_conn.cb_xprt) {svc_xprt_put (clp->cl_cb_conn.cb_xprt);
@@ -1010,6 +1031,7 @@ void nfsd4_do_callback_rpc(struct work_struct *w)nfsd4_release_cb (cb);return ; } + cb->cb_msg.rpc_cred = clp->cl_cb_cred;rpc_call_async (clnt, &cb->cb_msg,RPC_TASK_SOFT |RPC_TASK_SOFTCONN , cb->cb_ops, cb); }
@@ -1025,7 +1047,6 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp) cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL ]; cb->cb_msg.rpc_argp = cb; cb->cb_msg.rpc_resp = cb; - cb->cb_msg.rpc_cred = callback_cred; cb->cb_ops = &nfsd4_cb_recall_ops;
fs/nfsd/nfs4state.c +1 -0
@@ -957,6 +957,7 @@ void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4 new->se_cb_seq_nr =1 ; new->se_flags = cses->flags; new->se_cb_prog = cses->callback_prog; + new->se_cb_sec = cses->cb_sec;kref_init (&new->se_ref); idx =hash_sessionid (&new->se_sessionid);spin_lock (&client_lock);
fs/nfsd/state.h +1 -0
@@ -250,6 +250,7 @@ struct nfs4_client {#define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ 1 << NFSD4_CLIENT_CB_KILL)unsigned long cl_flags; +struct rpc_cred *cl_cb_cred;struct rpc_clnt *cl_cb_client;u32 cl_cb_ident;#define NFSD4_CB_UP 0
Signature · 1 line
1.7.9.5
PATCH 3/5 nfsd4: implement backchannel_ctl operation
In reply to J. Bruce FieldsFrom: "J. Bruce Fields" <[email protected]>
This operation is mandatory for servers to implement.
--- Documentation/filesystems/nfs/nfs41-server.txt | 7 +------ fs/nfsd/nfs4proc.c | 6 ++++++ fs/nfsd/nfs4state.c | 14 ++++++++++++++ fs/nfsd/nfs4xdr.c | 13 ++++++++++++- fs/nfsd/state.h | 5 +++++ fs/nfsd/xdr4.h | 2 ++ 6 files changed, 40 insertions(+), 7 deletions(-)
Documentation/filesystems/nfs/nfs41-server.txt +1 -6
@@ -39,11 +39,6 @@ interoperability problems with future clients. Known issues: from a linux client are possible, but we aren't really conformant with the spec (for example, we don't use kerberos on the backchannel correctly). - - Incomplete backchannel support: incomplete backchannel gss - support and no support for BACKCHANNEL_CTL mean that - callbacks (hence delegations and layouts) may not be - available and clients confused by the incomplete - implementation may fail. - We do not support SSV, which provides security for shared client-server state (thus preventing unauthorized tampering with locks and opens, for example). It is mandatory for
@@ -89,7 +84,7 @@ Operations | | MNI | or OPT) | | +----------------------+------------+--------------+----------------+ | ACCESS | REQ | | Section 18.1 | -NS | BACKCHANNEL_CTL | REQ | | Section 18.33 | +I | BACKCHANNEL_CTL | REQ | | Section 18.33 | I | BIND_CONN_TO_SESSION | REQ | | Section 18.34 | | CLOSE | REQ | | Section 18.2 | | COMMIT | REQ | | Section 18.3 |
fs/nfsd/nfs4proc.c +6 -0
@@ -1666,6 +1666,12 @@ static struct nfsd4_operation nfsd4_ops[] = { .op_name = "OP_EXCHANGE_ID", .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize, }, + [OP_BACKCHANNEL_CTL] = { + .op_func = (nfsd4op_func)nfsd4_backchannel_ctl, + .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, + .op_name = "OP_BACKCHANNEL_CTL", + .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + }, [OP_BIND_CONN_TO_SESSION] = { .op_func = (nfsd4op_func )nfsd4_bind_conn_to_session, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
fs/nfsd/nfs4state.c +14 -0
@@ -1865,6 +1865,20 @@ static __be32 nfsd4_map_bcts_dir(u32 *dir)return nfserr_inval; } +__be32 nfsd4_backchannel_ctl (struct svc_rqst *rqstp,struct nfsd4_compound_state *cstate,struct nfsd4_backchannel_ctl *bc) +{ +struct nfsd4_session *session = cstate->session; + +spin_lock (&client_lock); + session->se_cb_prog = bc->bc_cb_program; + session->se_cb_sec = bc->bc_cb_sec; +spin_unlock (&client_lock); + +nfsd4_probe_callback (session->se_client); + +return nfs_ok; +} +__be32 nfsd4_bind_conn_to_session (struct svc_rqst *rqstp,struct nfsd4_compound_state *cstate,struct nfsd4_bind_conn_to_session *bcts)
fs/nfsd/nfs4xdr.c +12 -1
@@ -483,6 +483,17 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_DECODE_TAIL ; } +static __be32 nfsd4_decode_backchannel_ctl (struct nfsd4_compoundargs *argp,struct nfsd4_backchannel_ctl *bc) +{ +DECODE_HEAD ; + +READ_BUF (4 ); +READ32 (bc->bc_cb_program); +nfsd4_decode_cb_sec (argp, &bc->bc_cb_sec); + +DECODE_TAIL ; +} +static __be32 nfsd4_decode_bind_conn_to_session (struct nfsd4_compoundargs *argp,struct nfsd4_bind_conn_to_session *bcts) {DECODE_HEAD ;
@@ -1536,7 +1547,7 @@ static nfsd4_dec nfsd41_dec_ops[] = { [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp,/* new operations for NFSv4.1 */ - [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session, [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
fs/nfsd/state.h +5 -0
@@ -166,6 +166,11 @@ struct nfsd4_create_session {struct nfsd4_cb_sec cb_sec; }; +struct nfsd4_backchannel_ctl { +u32 bc_cb_program; +struct nfsd4_cb_sec bc_cb_sec; +}; +struct nfsd4_bind_conn_to_session {struct nfs4_sessionid sessionid;u32 dir;
fs/nfsd/xdr4.h +2 -0
@@ -462,6 +462,7 @@ struct nfsd4_op {/* NFSv4.1 */ struct nfsd4_exchange_id exchange_id; +struct nfsd4_backchannel_ctl backchannel_ctl;struct nfsd4_bind_conn_to_session bind_conn_to_session;struct nfsd4_create_session create_session;struct nfsd4_destroy_session destroy_session;
@@ -566,6 +567,7 @@ extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, struct nfsd4_sequence *seq);extern __be32 nfsd4_exchange_id (struct svc_rqst *rqstp,struct nfsd4_compound_state *,struct nfsd4_exchange_id *); +extern __be32 nfsd4_backchannel_ctl (struct svc_rqst *,struct nfsd4_compound_state *,struct nfsd4_backchannel_ctl *);extern __be32 nfsd4_bind_conn_to_session (struct svc_rqst *,struct nfsd4_compound_state *,struct nfsd4_bind_conn_to_session *); extern __be32 nfsd4_create_session(struct svc_rqst *, struct nfsd4_compound_state *,
Signature · 1 line
1.7.9.5
PATCH 4/5 nfsd4: common helper to initialize callback work
In reply to J. Bruce FieldsFrom: "J. Bruce Fields" <[email protected]>
I've found it confusing having the only references to nfsd4_do_callback_rpc() in a different file.
--- fs/nfsd/nfs4callback.c | 7 ++++++- fs/nfsd/nfs4state.c | 4 ++-- fs/nfsd/state.h | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-)
fs/nfsd/nfs4callback.c +6 -1
@@ -1016,7 +1016,7 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)run_nfsd4_cb (cb); } -void nfsd4_do_callback_rpc (struct work_struct *w) +static void nfsd4_do_callback_rpc (struct work_struct *w) { struct nfsd4_callback *cb = container_of(w, struct nfsd4_callback, cb_work);struct nfs4_client *clp = cb->cb_clp;
@@ -1036,6 +1036,11 @@ void nfsd4_do_callback_rpc(struct work_struct *w) cb->cb_ops, cb); } +void nfsd4_init_callback (struct nfsd4_callback *cb) +{ +INIT_WORK (&cb->cb_work, nfsd4_do_callback_rpc); +} +void nfsd4_cb_recall (struct nfs4_delegation *dp) {struct nfsd4_callback *cb = &dp->dl_recall;
fs/nfsd/nfs4state.c +2 -2
@@ -340,7 +340,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svfh_copy_shallow (&dp->dl_fh, ¤t_fh->fh_handle); dp->dl_time =0 ;atomic_set (&dp->dl_count,1 ); -INIT_WORK (&dp->dl_recall.cb_work, nfsd4_do_callback_rpc); +nfsd4_init_callback (&dp->dl_recall);return dp; }
@@ -1313,7 +1313,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,INIT_LIST_HEAD (&clp->cl_lru);INIT_LIST_HEAD (&clp->cl_callbacks);spin_lock_init (&clp->cl_lock); -INIT_WORK (&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); +nfsd4_init_callback (&clp->cl_cb_null); clp->cl_time =get_seconds ();clear_bit (0 , &clp->cl_cb_slot_busy);rpc_init_wait_queue (&clp->cl_cb_waitq,"Backchannel slot table" );
fs/nfsd/state.h +1 -1
@@ -470,10 +470,10 @@ extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions);extern void nfs4_free_openowner (struct nfs4_openowner *);extern void nfs4_free_lockowner (struct nfs4_lockowner *);extern int set_callback_cred (void ); +extern void nfsd4_init_callback (struct nfsd4_callback *);extern void nfsd4_probe_callback (struct nfs4_client *clp);extern void nfsd4_probe_callback_sync (struct nfs4_client *clp);extern void nfsd4_change_callback (struct nfs4_client *clp,struct nfs4_cb_conn *); -extern void nfsd4_do_callback_rpc (struct work_struct *);extern void nfsd4_cb_recall (struct nfs4_delegation *dp);extern int nfsd4_create_callback_queue (void );extern void nfsd4_destroy_callback_queue (void );
Signature · 1 line
1.7.9.5
PATCH 5/5 nfsd4: backchannel should use client-provided security flavor
In reply to J. Bruce FieldsFrom: "J. Bruce Fields" <[email protected]>
For now this only adds support for AUTH_NULL. (Previously we assumed AUTH_UNIX.) We'll also need AUTH_GSS, which is trickier.
--- fs/nfsd/nfs4callback.c | 3 +-- fs/nfsd/nfs4xdr.c | 14 +++++++++++--- fs/nfsd/state.h | 1 + 3 files changed, 13 insertions(+), 5 deletions(-)
fs/nfsd/nfs4callback.c +1 -2
@@ -692,7 +692,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c args.bc_xprt = conn->cb_xprt; args.prognumber = clp->cl_cb_session->se_cb_prog; args.protocol =XPRT_TRANSPORT_BC_TCP ; - args.authflavor =RPC_AUTH_UNIX ; + args.authflavor = ses->se_cb_sec.flavor; }/* Create RPC client */ client =rpc_create (&args);
@@ -709,7 +709,6 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c clp->cl_cb_client = client; clp->cl_cb_cred = cred;return 0 ; - }static void warn_no_callback_path (struct nfs4_client *clp,int reason)
fs/nfsd/nfs4xdr.c +11 -3
@@ -425,7 +425,7 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *accessstatic __be32 nfsd4_decode_cb_sec (struct nfsd4_compoundargs *argp,struct nfsd4_cb_sec *cbs) {DECODE_HEAD ; -u32 dummy; +u32 dummy, uid, gid;char *machine_name;int i;int nr_secflavs;
@@ -433,12 +433,15 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_/* callback_sec_params4 */ READ_BUF (4 );READ32 (nr_secflavs); + cbs->flavor = (u32)(-1 );for (i =0 ; i < nr_secflavs; ++i) {READ_BUF (4 );READ32 (dummy);switch (dummy) {case RPC_AUTH_NULL :/* Nothing to read */ +if (cbs->flavor == (u32)(-1 )) + cbs->flavor =RPC_AUTH_NULL ;break ;case RPC_AUTH_UNIX :READ_BUF (8 );
@@ -452,13 +455,18 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_/* uid, gid */ READ_BUF (8 ); -READ32 (cbs->uid); -READ32 (cbs->gid); +READ32 (uid); +READ32 (gid);/* more gids */ READ_BUF (4 );READ32 (dummy);READ_BUF (dummy *4 ); +if (cbs->flavor == (u32)(-1 )) { + cbs->uid = uid; + cbs->gid = gid; + cbs->flavor =RPC_AUTH_UNIX ; + }break ;case RPC_AUTH_GSS : dprintk("RPC_AUTH_GSS callback secflavor "
fs/nfsd/state.h +1 -0
@@ -151,6 +151,7 @@ struct nfsd4_channel_attrs { };struct nfsd4_cb_sec { +u32 flavor;/* (u32)(-1) used to mean "no valid flavor" */ u32 uid;u32 gid; };
Signature · 1 line
1.7.9.5
Quoted 3 lines · J. Bruce Fields
This is an incomplete implementation of the (mandatory) NFSv4.1 backchannel security negotation, only enough to handle
auth_unixandauth_null;auth_gsswill need more work.
And I've also pushed out corresponding pynfs tests to
git://linux-nfs.org/~bfields/pynfs.git
Fred, could you please pull the master branch from there? It's got a hundred-some commits outstanding at this point.
--b.