/** * FSAL_proxy_setclientid_force: * Client ID negociation * * \param p_context (input): * Authentication context for the operation (user,...). * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes can be returned : * ERR_FSAL_ACCESS, ERR_FSAL_IO, ... */ static fsal_status_t FSAL_proxy_setclientid_force(proxyfsal_op_context_t * p_context) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; #define FSAL_CLIENTID_NB_OP_ALLOC 1 nfs_argop4 argoparray[FSAL_CLIENTID_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_CLIENTID_NB_OP_ALLOC]; nfs_client_id4 nfsclientid; cb_client4 cbproxy; char clientid_name[MAXNAMLEN+1]; char cbaddr[MAXNAMLEN+1]; char cbnetid[MAXNAMLEN+1]; struct timeval timeout = TIMEOUTRPC; int fd; struct sockaddr_in sin; socklen_t l = sizeof(sin); LogEvent( COMPONENT_FSAL, "Negotiating a new ClientId with the remote server" ) ; /* sanity checks. */ if(!p_context) ReturnCode(ERR_FSAL_FAULT, 0); if(!CLNT_CONTROL(p_context->rpc_client, CLGET_FD, &fd)) ReturnCode(ERR_FSAL_FAULT, EBADF); if(getsockname(fd, &sin, &l)) ReturnCode(ERR_FSAL_FAULT, errno); /* Client id negociation is to be done only one time for the whole FSAL */ P(fsal_clientid_mutex_renew); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; snprintf(clientid_name, MAXNAMLEN, "%s(%d) - GANESHA NFSv4 Proxy", inet_ntop(AF_INET, &sin.sin_addr, cbaddr, sizeof(cbaddr)), getpid()); nfsclientid.id.id_len = strlen(clientid_name); nfsclientid.id.id_val = clientid_name; snprintf(nfsclientid.verifier, NFS4_VERIFIER_SIZE, "%x", (int)ServerBootTime); cbproxy.cb_program = 0; strncpy(cbnetid, "tcp", MAXNAMLEN); strncpy(cbaddr, "127.0.0.1", MAXNAMLEN); cbproxy.cb_location.r_netid = cbnetid; cbproxy.cb_location.r_addr = cbaddr; COMPOUNDV4_ARG_ADD_OP_SETCLIENTID(argnfs4, nfsclientid, cbproxy); TakeTokenFSCall(); p_context->credential.user = 0; p_context->credential.group = 0; p_context->credential.nbgroups = 0; /* Call the NFSv4 function */ rc = COMPOUNDV4_EXECUTE_SIMPLE(p_context, argnfs4, resnfs4); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); V(fsal_clientid_mutex_renew); ReturnCode(ERR_FSAL_IO, rc); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) { V(fsal_clientid_mutex_renew); return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_InitClientContext); } /* Step 2: Confirm the client id */ argnfs4.minorversion = 0; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; argnfs4.argarray.argarray_val[0].argop = NFS4_OP_SETCLIENTID_CONFIRM; argnfs4.argarray.argarray_val[0].nfs_argop4_u.opsetclientid_confirm.clientid = resnfs4.resarray.resarray_val[0].nfs_resop4_u.opsetclientid.SETCLIENTID4res_u. resok4.clientid; memcpy((char *)argnfs4.argarray.argarray_val[0].nfs_argop4_u.opsetclientid_confirm. setclientid_confirm, (char *)resnfs4.resarray.resarray_val[0].nfs_resop4_u.opsetclientid. SETCLIENTID4res_u.resok4.setclientid_confirm, NFS4_VERIFIER_SIZE); argnfs4.argarray.argarray_len = 1; /* Call the NFSv4 function */ TakeTokenFSCall(); rc = COMPOUNDV4_EXECUTE_SIMPLE(p_context, argnfs4, resnfs4); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); V(fsal_clientid_mutex_renew); ReturnCode(ERR_FSAL_IO, rc); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) { V(fsal_clientid_mutex_renew); return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_InitClientContext); } /* Keep the confirmed client id */ fsal_clientid = argnfs4.argarray.argarray_val[0].nfs_argop4_u.opsetclientid_confirm.clientid; clientid_renewed = time( NULL ) ; V(fsal_clientid_mutex_renew); p_context->clientid = fsal_clientid; p_context->last_lease_renewal = 0; /* Needs to be renewed */ ReturnCode(ERR_FSAL_NO_ERROR, 0); } /* FSAL_proxy_setclientid_force */
/** * FSAL_proxy_setclientid_force: * Client ID negociation * * \param p_context (input): * Authentication context for the operation (user,...). * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes can be returned : * ERR_FSAL_ACCESS, ERR_FSAL_IO, ... */ fsal_status_t FSAL_proxy_setclientid_force(proxyfsal_op_context_t * p_context) { int rc; fsal_status_t fsal_status; COMPOUND4args argnfs4; COMPOUND4res resnfs4; #define FSAL_CLIENTID_NB_OP_ALLOC 1 nfs_argop4 argoparray[FSAL_CLIENTID_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_CLIENTID_NB_OP_ALLOC]; nfs_client_id4 nfsclientid; cb_client4 cbproxy; char clientid_name[MAXNAMLEN]; char cbaddr[MAXNAMLEN]; char cbnetid[MAXNAMLEN]; clientid4 resultclientid; struct timeval timeout = TIMEOUTRPC; LogEvent( COMPONENT_FSAL, "Negociating a new ClientId with the remote server" ) ; /* sanity checks. */ if(!p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_InitClientContext); /* Client id negociation is to be done only one time for the whole FSAL */ P(fsal_clientid_mutex_renew); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; snprintf(clientid_name, MAXNAMLEN, "GANESHA NFSv4 Proxy Pid=%u", getpid()); nfsclientid.id.id_len = strlen(clientid_name); nfsclientid.id.id_val = clientid_name; snprintf(nfsclientid.verifier, NFS4_VERIFIER_SIZE, "%x", (int)ServerBootTime); cbproxy.cb_program = 0; strncpy(cbnetid, "tcp", MAXNAMLEN); strncpy(cbaddr, "127.0.0.1", MAXNAMLEN); #ifdef _USE_NFS4_1 cbproxy.cb_location.na_r_netid = cbnetid; cbproxy.cb_location.na_r_addr = cbaddr; #else cbproxy.cb_location.r_netid = cbnetid; cbproxy.cb_location.r_addr = cbaddr; #endif COMPOUNDV4_ARG_ADD_OP_SETCLIENTID(argnfs4, nfsclientid, cbproxy); TakeTokenFSCall(); p_context->credential.user = 0; p_context->credential.group = 0; p_context->credential.nbgroups = 0; /* Call the NFSv4 function */ rc = COMPOUNDV4_EXECUTE_SIMPLE(p_context, argnfs4, resnfs4); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); V(fsal_clientid_mutex_renew); Return(ERR_FSAL_IO, rc, INDEX_FSAL_unlink); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) { V(fsal_clientid_mutex_renew); return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_InitClientContext); } resultclientid = resnfs4.resarray.resarray_val[0].nfs_resop4_u.opsetclientid.SETCLIENTID4res_u. resok4.clientid; /* Step 2: Confirm the client id */ argnfs4.minorversion = 0; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; argnfs4.argarray.argarray_val[0].argop = NFS4_OP_SETCLIENTID_CONFIRM; argnfs4.argarray.argarray_val[0].nfs_argop4_u.opsetclientid_confirm.clientid = resnfs4.resarray.resarray_val[0].nfs_resop4_u.opsetclientid.SETCLIENTID4res_u. resok4.clientid; memcpy((char *)argnfs4.argarray.argarray_val[0].nfs_argop4_u.opsetclientid_confirm. setclientid_confirm, (char *)resnfs4.resarray.resarray_val[0].nfs_resop4_u.opsetclientid. SETCLIENTID4res_u.resok4.setclientid_confirm, NFS4_VERIFIER_SIZE); argnfs4.argarray.argarray_len = 1; /* Call the NFSv4 function */ rc = COMPOUNDV4_EXECUTE_SIMPLE(p_context, argnfs4, resnfs4); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); V(fsal_clientid_mutex_renew); Return(ERR_FSAL_IO, rc, INDEX_FSAL_unlink); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_InitClientContext); /* Keep the confirmed client id */ fsal_clientid = argnfs4.argarray.argarray_val[0].nfs_argop4_u.opsetclientid_confirm.clientid; clientid_renewed = time( NULL ) ; V(fsal_clientid_mutex_renew); p_context->clientid = fsal_clientid; p_context->last_lease_renewal = 0; /* Needs to be renewed */ fsal_status.major = ERR_FSAL_NO_ERROR; fsal_status.minor = 0; return fsal_status; } /* FSAL_proxy_setclientid_force */