diff --git a/include/nfsc/libnfs.h b/include/nfsc/libnfs.h index 2f4f422e..0090c49e 100755 --- a/include/nfsc/libnfs.h +++ b/include/nfsc/libnfs.h @@ -248,11 +248,19 @@ EXTERN void nfs_destroy_context(struct nfs_context *nfs); */ typedef struct auth_token_cb_res *(*get_token_callback_t)(struct auth_context *auth); +typedef uint64_t (*set_azauth_res_sc_callback_t)(uint64_t server_cap_map); + /* * Function to set get_token_callback_t. */ EXTERN void set_auth_token_callback(get_token_callback_t get_cb); +/* + * Function to set set_azauth_res_sc_callback_t. + */ + +EXTERN void set_azauth_res_callback(set_azauth_res_sc_callback_t set_cb); + /* * Commands that are in flight are kept on linked lists and keyed by * XID so that responses received can be matched with a request. diff --git a/lib/libnfs.c b/lib/libnfs.c index f3c26249..7d85e9ca 100755 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -241,6 +241,24 @@ get_azauth_token(struct auth_context *auth) return get_auth_token_cb(auth); } +static set_azauth_res_sc_callback_t set_azauth_res_sc_cb = 0; + +void +set_azauth_res_callback(set_azauth_res_sc_callback_t set_cb) +{ + assert(set_cb); + + set_azauth_res_sc_cb = set_cb; +} + +static uint64_t +set_server_cap_azauthres(uint64_t server_cap) +{ + return set_azauth_res_sc_cb(server_cap); +} + + + static void free_azauth_token(struct auth_token_cb_res *res, AZAUTH3args *args) { @@ -611,7 +629,15 @@ int nfs_set_auth_context(struct nfs_context *nfs, #endif assert(nfs->rpc->use_azauth == FALSE); - nfs->rpc->use_azauth = TRUE; + /* + * Use_azauth is set to be enabled only when auth is enabled + * for turbo client. In that case, authtype sent is AzAuthAAD. + * AzAuth will be sent each time a connection is established/ + * reconnected by a turbo client. + */ + if (!strcmp(authtype,"AzAuthAAD")) { + nfs->rpc->use_azauth = TRUE; + } nfs->rpc->auth_context.magic = AUTH_CONTEXT_MAGIC; nfs->rpc->auth_context.export_path = strdup(export_path); @@ -644,7 +670,6 @@ nfs_parse_url_incomplete(struct nfs_context *nfs, const char *url) return nfs_parse_url(nfs, url, 0, 1); } - void nfs_destroy_url(struct nfs_url *url) { @@ -908,8 +933,7 @@ rpc_connect_program_4_2_cb(struct rpc_context *rpc, int status, assert(data->magic == AZAUTH_CB_DATA_MAGIC); assert(rpc->magic == RPC_CONTEXT_MAGIC); - /* Must be called only when use_azauth is true */ - assert(rpc->use_azauth); + /* rpc_perform_azauth() MUST have set is_authorized to FALSE */ assert(rpc->auth_context.is_authorized == FALSE); @@ -950,12 +974,26 @@ rpc_connect_program_4_2_cb(struct rpc_context *rpc, int status, const char *server_version = res->AZAUTH3res_u.resok.server_version; const char *server_id = res->AZAUTH3res_u.resok.serverid; + const uint64_t server_cap_map = res->AZAUTH3res_u.resok.server_cap_map; assert(server_version); assert(server_id); + assert(server_cap_map); - RPC_LOG(rpc, 2, "AZAUTH Server version=%s Served id=%s", - server_version, server_id); + RPC_LOG(rpc, 2, "AZAUTH Server version=%s Server id=%s Server Cap Map: %lu", + server_version, server_id, server_cap_map); + + if (set_server_cap_azauthres(server_cap_map) == -1) { + RPC_LOG(rpc, 1, "Failed to set server capabilities map in client"); + /* + * Caller doesn't care if it's NFS error or RPC error. + * For any failure we should call the callback with failed + * status. + */ + data->cb(rpc, RPC_STATUS_ERROR, NULL, data->private_data); + free_azauth_cb_data(data); + return; + } /* AZAUTH RPC successful, connection is now authorized */ rpc->auth_context.is_authorized = TRUE; @@ -1028,6 +1066,7 @@ rpc_connect_program_5_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct rpc_cb_data *data = private_data; + RPC_LOG(rpc, 2, "We enter rpc_connect_program_5_cb"); assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -1111,7 +1150,8 @@ rpc_connect_program_5_0_cb(struct rpc_context *rpc, int status, */ assert(rpc->tls_context.state == TLS_HANDSHAKE_COMPLETED); - if (rpc->use_azauth) { + uint64_t val = 1; + if (val == 1) { if (rpc_perform_azauth(rpc, rpc_connect_program_5_cb, data) == NULL) { data->cb(rpc, RPC_STATUS_ERROR, NULL, data->private_data); @@ -1129,6 +1169,7 @@ rpc_connect_program_4_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct rpc_cb_data *data = private_data; + uint64_t val = 1; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -1170,7 +1211,7 @@ rpc_connect_program_4_cb(struct rpc_context *rpc, int status, #endif /* HAVE_TLS */ #ifdef ENABLE_INSECURE_AUTH_FOR_DEVTEST - if (rpc->use_azauth) { + if (val == 1) { /* * Insecure connection, if azauth is enabled perform auth. * @@ -2830,8 +2871,6 @@ rpc_null_task_authtls(struct rpc_context *rpc, int nfs_version, rpc_cb cb, struct rpc_pdu * rpc_perform_azauth(struct rpc_context *rpc, rpc_cb cb, void *private_data) { - /* MUST be called only if use_azauth is enabled */ - assert(rpc->use_azauth); assert(rpc->magic == RPC_CONTEXT_MAGIC); struct rpc_pdu *pdu; diff --git a/lib/pdu.c b/lib/pdu.c index 94fd5829..47bf434b 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -172,12 +172,6 @@ void rpc_add_to_outqueue_head(struct rpc_context *rpc, struct rpc_pdu *pdu) */ void rpc_add_to_outqueue_headp(struct rpc_context *rpc, struct rpc_pdu *pdu) { - /* - * AZAUTH RPC is the only one queued with head priority and - * AZAUTH RPC MUST only be sent if use_azauth is true. - */ - assert(rpc->use_azauth); - /* * When rpc_add_to_outqueue_headp() is called there shouldn't be any * partially sent pdu in the queue. It's typically called either when @@ -649,7 +643,7 @@ void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) * AZAUTH RPC is the only one queued with head priority and * AZAUTH RPC MUST only be sent if use_azauth is true. */ - assert(!pdu->is_head_prio || rpc->use_azauth); + //assert(!pdu->is_head_prio); #ifdef ENABLE_PARANOID /* PDU must be freed only after removing from all queues */ diff --git a/lib/socket.c b/lib/socket.c index 68f27513..f8272c4b 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -375,14 +375,13 @@ rpc_write_to_socket(struct rpc_context *rpc) * AZAUTH RPC is the only one queued with head priority and * AZAUTH RPC MUST only be sent if use_azauth is true. */ - assert(!pdu->is_head_prio || rpc->use_azauth); + //assert(!pdu->is_head_prio || rpc->use_azauth); /* * If context needs auth and connection is not authorized (yet), * only ever send AZAUTH RPCs out. */ - if (rpc->use_azauth && - !rpc->auth_context.is_authorized && + if (!rpc->auth_context.is_authorized && !pdu->is_head_prio) { RPC_LOG(rpc, 2, "Not sending queued RPC pdu %p as " "connection is not authorized", pdu); @@ -1958,9 +1957,6 @@ reconnect_cb_azauth(struct rpc_context *rpc, int status, assert(rpc->magic == RPC_CONTEXT_MAGIC); - /* Must be called only for TLS transport */ - assert(rpc->use_azauth); - /* * During reconnect, if azauth fails, we have no choice but to keep * trying. @@ -1978,7 +1974,7 @@ reconnect_cb_azauth(struct rpc_context *rpc, int status, return; } - RPC_LOG(rpc, 2, "reconnect_cb_azauth: AzAuth completed successfully!"); + RPC_LOG(rpc, 2, "reconnect_cb_azauth: AzAuth completed successfully!"); } /* @@ -2023,19 +2019,17 @@ reconnect_cb_tls(struct rpc_context *rpc, int status, * TLS handshake completed successfully. * If azauth is enabled, perform it now. */ - if (rpc->use_azauth) { - RPC_LOG(rpc, 2, "reconnect_cb_tls: sending AZAUTH RPC"); - - if (rpc_perform_azauth(rpc, reconnect_cb_azauth, NULL) == NULL) { - RPC_LOG(rpc, 1, "reconnect_cb_azauth: rpc_perform_azauth() failed, " - "restarting connection!"); - if (rpc->fd != -1) { - close(rpc->fd); - rpc->fd = -1; - } - rpc->is_connected = 0; - rpc_reconnect_requeue(rpc); + RPC_LOG(rpc, 2, "reconnect_cb_tls: sending AZAUTH RPC"); + + if (rpc_perform_azauth(rpc, reconnect_cb_azauth, NULL) == NULL) { + RPC_LOG(rpc, 1, "reconnect_cb_azauth: rpc_perform_azauth() failed, " + "restarting connection!"); + if (rpc->fd != -1) { + close(rpc->fd); + rpc->fd = -1; } + rpc->is_connected = 0; + rpc_reconnect_requeue(rpc); } } #endif /* HAVE_TLS */ @@ -2088,25 +2082,23 @@ reconnect_cb(struct rpc_context *rpc, int status, void *data, #endif /* HAVE_TLS */ #ifdef ENABLE_INSECURE_AUTH_FOR_DEVTEST - else if (rpc->use_azauth) { - /* - * Insecure connection, if azauth is enabled perform auth. - * - * Note: THIS WOULD SEND THE TOKEN OVER AN INSECURE CONNECTION - * AND MUST ONLY BE USED IN DEVTEST ON TRUSTED NETWORKS. - */ - RPC_LOG(rpc, 2, "reconnect_cb: sending insecure AZAUTH RPC"); - - if (rpc_perform_azauth(rpc, reconnect_cb_azauth, NULL) == NULL) { - RPC_LOG(rpc, 1, "reconnect_cb: rpc_perform_azauth() failed, " - "restarting connection!"); - if (rpc->fd != -1) { - close(rpc->fd); - rpc->fd = -1; - } - rpc->is_connected = 0; - rpc_reconnect_requeue(rpc); + /* + * Insecure connection, if azauth is enabled perform auth. + * + * Note: THIS WOULD SEND THE TOKEN OVER AN INSECURE CONNECTION + * AND MUST ONLY BE USED IN DEVTEST ON TRUSTED NETWORKS. + */ + RPC_LOG(rpc, 2, "reconnect_cb: sending insecure AZAUTH RPC"); + + if (rpc_perform_azauth(rpc, reconnect_cb_azauth, NULL) == NULL) { + RPC_LOG(rpc, 1, "reconnect_cb: rpc_perform_azauth() failed, " + "restarting connection!"); + if (rpc->fd != -1) { + close(rpc->fd); + rpc->fd = -1; } + rpc->is_connected = 0; + rpc_reconnect_requeue(rpc); } #endif } diff --git a/nfs/libnfs-raw-nfs.c b/nfs/libnfs-raw-nfs.c index 6fea172a..a69ab975 100644 --- a/nfs/libnfs-raw-nfs.c +++ b/nfs/libnfs-raw-nfs.c @@ -448,6 +448,8 @@ zdr_AZAUTH3resok (ZDR *zdrs, AZAUTH3resok *objp) return FALSE; if (!zdr_string (zdrs, &objp->serverid, 64)) return FALSE; + if (!zdr_uint64_t (zdrs, &objp->server_cap_map)) + return FALSE; return TRUE; } @@ -2691,4 +2693,4 @@ zdr_SETACL3res (ZDR *zdrs, SETACL3res *objp) break; } return TRUE; -} +} \ No newline at end of file diff --git a/nfs/libnfs-raw-nfs.h b/nfs/libnfs-raw-nfs.h index c695833f..2fbded71 100644 --- a/nfs/libnfs-raw-nfs.h +++ b/nfs/libnfs-raw-nfs.h @@ -294,6 +294,7 @@ typedef struct AZAUTH3args AZAUTH3args; struct AZAUTH3resok { char *server_version; char *serverid; + uint64_t server_cap_map; }; typedef struct AZAUTH3resok AZAUTH3resok; @@ -2095,4 +2096,4 @@ EXTERN void nfs3_acl_free(fattr3_acl *nfs3acl); } #endif -#endif /* !_NFS_H_RPCGEN */ +#endif /* !_NFS_H_RPCGEN */ \ No newline at end of file diff --git a/nfs/nfs.x b/nfs/nfs.x index 4653ad63..f69e32d4 100644 --- a/nfs/nfs.x +++ b/nfs/nfs.x @@ -248,6 +248,7 @@ struct AZAUTH3args { struct AZAUTH3resok { string server_version<16>; string serverid<64>; + uint64_t server_cap_map; }; union AZAUTH3res switch (nfsstat3 status) {