ACCESS3res *res;
struct nfs_cb_data *data = private_data;
struct nfs_context *nfs = data->nfs;
- unsigned int nfsmode = 0;
+ unsigned int mode = 0;
assert(rpc->magic == RPC_CONTEXT_MAGIC);
return;
}
- if (data->continue_int & R_OK) {
- nfsmode |= ACCESS3_READ;
+ if ((data->continue_int & R_OK) && (res->ACCESS3res_u.resok.access & ACCESS3_READ)) {
+ mode |= R_OK;
}
- if (data->continue_int & W_OK) {
- nfsmode |= ACCESS3_MODIFY;
+ if ((data->continue_int & W_OK) && (res->ACCESS3res_u.resok.access & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE))) {
+ mode |= W_OK;
}
- if (data->continue_int & X_OK) {
- nfsmode |= ACCESS3_EXECUTE;
+ if ((data->continue_int & X_OK) && (res->ACCESS3res_u.resok.access & (ACCESS3_LOOKUP | ACCESS3_EXECUTE))) {
+ mode |= X_OK;
}
- if (res->ACCESS3res_u.resok.access != nfsmode) {
+ if (data->continue_int != mode) {
rpc_set_error(nfs->rpc, "NFS: ACCESS denied. Required access %c%c%c. Allowed access %c%c%c",
- nfsmode&ACCESS3_READ?'r':'-',
- nfsmode&ACCESS3_MODIFY?'w':'-',
- nfsmode&ACCESS3_EXECUTE?'x':'-',
- res->ACCESS3res_u.resok.access&ACCESS3_READ?'r':'-',
- res->ACCESS3res_u.resok.access&ACCESS3_MODIFY?'w':'-',
- res->ACCESS3res_u.resok.access&ACCESS3_EXECUTE?'x':'-');
+ data->continue_int&R_OK?'r':'-',
+ data->continue_int&W_OK?'w':'-',
+ data->continue_int&X_OK?'x':'-',
+ mode&R_OK?'r':'-',
+ mode&W_OK?'w':'-',
+ mode&X_OK?'x':'-');
data->cb(-EACCES, nfs, rpc_get_error(nfs->rpc), data->private_data);
free_nfs_cb_data(data);
return;
nfsmode |= ACCESS3_READ;
}
if (data->continue_int & W_OK) {
- nfsmode |= ACCESS3_MODIFY;
+ nfsmode |= ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE;
}
if (data->continue_int & X_OK) {
- nfsmode |= ACCESS3_EXECUTE;
+ nfsmode |= ACCESS3_LOOKUP | ACCESS3_EXECUTE;
}
memset(&args, 0, sizeof(ACCESS3args));
int nfs_access_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data)
{
- if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_access_continue_internal, NULL, NULL, mode) != 0) {
+ if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_access_continue_internal, NULL, NULL, mode & (R_OK | W_OK | X_OK)) != 0) {
rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components");
return -1;
}