1 /* -*-  mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil;  -*- */
2 /*
3    Copyright (C) 2016 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU Lesser General Public License as published by
7    the Free Software Foundation; either version 2.1 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public License
16    along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifdef WIN32
20 #include <win32/win32_compat.h>
21 #else
22 #include <sys/stat.h>
23 #endif/*WIN32*/
24 
25 #include <stdio.h>
26 #include <errno.h>
27 #include <string.h>
28 #include "libnfs-zdr.h"
29 #include "libnfs.h"
30 #include "libnfs-raw.h"
31 #include "libnfs-private.h"
32 #include "libnfs-raw-nfs4.h"
33 
34 char *
nfsstat4_to_str(int error)35 nfsstat4_to_str(int error)
36 {
37 	switch (error) {
38         case NFS4_OK: return "NFS4_OK"; break;
39         case NFS4ERR_PERM: return "NFS4ERR_PERM"; break;
40         case NFS4ERR_NOENT: return "NFS4ERR_NOENT"; break;
41         case NFS4ERR_IO: return "NFS4ERR_IO"; break;
42         case NFS4ERR_NXIO: return "NFS4ERR_NXIO"; break;
43         case NFS4ERR_ACCESS: return "NFS4ERR_ACCESS"; break;
44         case NFS4ERR_EXIST: return "NFS4ERR_EXIST"; break;
45         case NFS4ERR_XDEV: return "NFS4ERR_XDEV"; break;
46         case NFS4ERR_NOTDIR: return "NFS4ERR_NOTDIR"; break;
47         case NFS4ERR_ISDIR: return "NFS4ERR_ISDIR"; break;
48         case NFS4ERR_INVAL: return "NFS4ERR_INVAL"; break;
49         case NFS4ERR_FBIG: return "NFS4ERR_FBIG"; break;
50         case NFS4ERR_NOSPC: return "NFS4ERR_NOSPC"; break;
51         case NFS4ERR_ROFS: return"NFS4ERR_ROFS"; break;
52         case NFS4ERR_MLINK: return "NFS4ERR_MLINK"; break;
53         case NFS4ERR_NAMETOOLONG: return "NFS4ERR_NAMETOOLONG"; break;
54         case NFS4ERR_NOTEMPTY: return "NFS4ERR_NOTEMPTY"; break;
55         case NFS4ERR_DQUOT: return "NFS4ERR_DQUOT"; break;
56         case NFS4ERR_STALE: return "NFS4ERR_STALE"; break;
57         case NFS4ERR_BADHANDLE: return "NFS4ERR_BADHANDLE"; break;
58         case NFS4ERR_BAD_COOKIE: return "NFS4ERR_BAD_COOKIE"; break;
59         case NFS4ERR_NOTSUPP: return "NFS4ERR_NOTSUPP"; break;
60         case NFS4ERR_TOOSMALL: return "NFS4ERR_TOOSMALL"; break;
61         case NFS4ERR_SERVERFAULT: return "NFS4ERR_SERVERFAULT"; break;
62         case NFS4ERR_BADTYPE: return "NFS4ERR_BADTYPE"; break;
63         case NFS4ERR_DELAY: return "NFS4ERR_DELAY"; break;
64         case NFS4ERR_SAME: return "NFS4ERR_SAME"; break;
65         case NFS4ERR_DENIED: return "NFS4ERR_DENIED"; break;
66         case NFS4ERR_EXPIRED: return "NFS4ERR_EXPIRED"; break;
67         case NFS4ERR_LOCKED: return "NFS4ERR_LOCKED"; break;
68         case NFS4ERR_GRACE: return "NFS4ERR_GRACE"; break;
69         case NFS4ERR_FHEXPIRED: return "NFS4ERR_FHEXPIRED"; break;
70         case NFS4ERR_SHARE_DENIED: return "NFS4ERR_SHARE_DENIED"; break;
71         case NFS4ERR_WRONGSEC: return "NFS4ERR_WRONGSEC"; break;
72         case NFS4ERR_CLID_INUSE: return "NFS4ERR_CLID_INUSE"; break;
73         case NFS4ERR_RESOURCE: return "NFS4ERR_RESOURCE"; break;
74         case NFS4ERR_MOVED: return "NFS4ERR_MOVED"; break;
75         case NFS4ERR_NOFILEHANDLE: return "NFS4ERR_NOFILEHANDLE"; break;
76         case NFS4ERR_MINOR_VERS_MISMATCH:
77                 return "NFS4ERR_MINOR_VERS_MISMATCH"; break;
78         case NFS4ERR_STALE_CLIENTID: return "NFS4ERR_STALE_CLIENTID"; break;
79         case NFS4ERR_STALE_STATEID: return "NFS4ERR_STALE_STATEID"; break;
80         case NFS4ERR_OLD_STATEID: return "NFS4ERR_OLD_STATEID"; break;
81         case NFS4ERR_BAD_STATEID: return "NFS4ERR_BAD_STATEID"; break;
82         case NFS4ERR_BAD_SEQID: return "NFS4ERR_BAD_SEQID"; break;
83         case NFS4ERR_NOT_SAME: return "NFS4ERR_NOT_SAME"; break;
84         case NFS4ERR_LOCK_RANGE: return "NFS4ERR_LOCK_RANGE"; break;
85         case NFS4ERR_SYMLINK: return "NFS4ERR_SYMLINK"; break;
86         case NFS4ERR_RESTOREFH: return "NFS4ERR_RESTOREFH"; break;
87         case NFS4ERR_LEASE_MOVED: return "NFS4ERR_LEASE_MOVED"; break;
88         case NFS4ERR_ATTRNOTSUPP: return "NFS4ERR_ATTRNOTSUPP"; break;
89         case NFS4ERR_NO_GRACE: return "NFS4ERR_NO_GRACE"; break;
90         case NFS4ERR_RECLAIM_BAD: return "NFS4ERR_RECLAIM_BAD"; break;
91         case NFS4ERR_RECLAIM_CONFLICT: return "NFS4ERR_RECLAIM_CONFLICT"; break;
92         case NFS4ERR_BADZDR: return "NFS4ERR_BADZDR"; break;
93         case NFS4ERR_LOCKS_HELD: return "NFS4ERR_LOCKS_HELD"; break;
94         case NFS4ERR_OPENMODE: return "NFS4ERR_OPENMODE"; break;
95         case NFS4ERR_BADOWNER: return "NFS4ERR_BADOWNER"; break;
96         case NFS4ERR_BADCHAR: return "NFS4ERR_BADCHAR"; break;
97         case NFS4ERR_BADNAME: return "NFS4ERR_BADNAME"; break;
98         case NFS4ERR_BAD_RANGE: return "NFS4ERR_BAD_RANGE"; break;
99         case NFS4ERR_LOCK_NOTSUPP: return "NFS4ERR_LOCK_NOTSUPP"; break;
100         case NFS4ERR_OP_ILLEGAL: return "NFS4ERR_OP_ILLEGAL"; break;
101         case NFS4ERR_DEADLOCK: return "NFS4ERR_DEADLOCK"; break;
102         case NFS4ERR_FILE_OPEN: return "NFS4ERR_FILE_OPEN"; break;
103         case NFS4ERR_ADMIN_REVOKED: return "NFS4ERR_ADMIN_REVOKED"; break;
104         case NFS4ERR_CB_PATH_DOWN: return "NFS4ERR_CB_PATH_DOWN"; break;
105 	};
106 	return "unknown nfsv4 error";
107 }
108 
109 int
nfsstat4_to_errno(int error)110 nfsstat4_to_errno(int error)
111 {
112 	switch (error) {
113         case NFS4_OK: return 0;
114         case NFS4ERR_PERM: return -EPERM;
115         case NFS4ERR_NOENT: return -ENOENT ;
116         case NFS4ERR_IO: return -EIO;
117         case NFS4ERR_NXIO: return -ENXIO;
118         case NFS4ERR_ACCESS: return -EACCES ;
119         case NFS4ERR_EXIST: return -EEXIST;
120         case NFS4ERR_XDEV: return -EXDEV;
121         case NFS4ERR_NOTDIR: return -ENOTDIR ;
122         case NFS4ERR_ISDIR: return -EISDIR ;
123         case NFS4ERR_INVAL: return -EINVAL;
124         case NFS4ERR_FBIG: return -EFBIG;
125         case NFS4ERR_NOSPC: return -ENOSPC;
126         case NFS4ERR_ROFS: return -EROFS;
127         case NFS4ERR_MLINK: return -EMLINK;
128         case NFS4ERR_NAMETOOLONG: return -ENAMETOOLONG;
129         case NFS4ERR_NOTEMPTY: return -ENOTEMPTY;
130         case NFS4ERR_DQUOT: return -ERANGE;
131         case NFS4ERR_STALE: return -EIO;
132         case NFS4ERR_BADHANDLE: return -EINVAL;
133         case NFS4ERR_BAD_COOKIE: return -EINVAL;
134         case NFS4ERR_NOTSUPP: return -EINVAL;
135         case NFS4ERR_TOOSMALL: return -EIO;
136         case NFS4ERR_SERVERFAULT: return -EIO;
137         case NFS4ERR_BADTYPE: return -EINVAL;
138         case NFS4ERR_DELAY: return -EIO;
139         case NFS4ERR_SAME: return -EIO;
140         case NFS4ERR_DENIED: return -EIO;
141         case NFS4ERR_EXPIRED: return -EIO;
142         case NFS4ERR_LOCKED: return -EIO;
143         case NFS4ERR_GRACE: return -EIO;
144         case NFS4ERR_FHEXPIRED: return -EIO;
145         case NFS4ERR_SHARE_DENIED: return -EIO;
146         case NFS4ERR_WRONGSEC: return -EIO;
147         case NFS4ERR_CLID_INUSE: return -EIO;
148         case NFS4ERR_RESOURCE: return -EIO;
149         case NFS4ERR_MOVED: return -EIO;
150         case NFS4ERR_NOFILEHANDLE: return -EIO;
151         case NFS4ERR_MINOR_VERS_MISMATCH: return -EIO;
152         case NFS4ERR_STALE_CLIENTID: return -EIO;
153         case NFS4ERR_STALE_STATEID: return -EIO;
154         case NFS4ERR_OLD_STATEID: return -EIO;
155         case NFS4ERR_BAD_STATEID: return -EINVAL;
156         case NFS4ERR_BAD_SEQID: return -EINVAL;
157         case NFS4ERR_NOT_SAME: return -EIO;
158         case NFS4ERR_LOCK_RANGE: return -EIO;
159         case NFS4ERR_SYMLINK: return -EIO;
160         case NFS4ERR_RESTOREFH: return -EIO;
161         case NFS4ERR_ATTRNOTSUPP: return -EINVAL;
162         case NFS4ERR_NO_GRACE: return -EIO;
163         case NFS4ERR_RECLAIM_BAD: return -EIO;
164         case NFS4ERR_RECLAIM_CONFLICT: return -EIO;
165         case NFS4ERR_BADZDR: return -EINVAL;
166         case NFS4ERR_LOCKS_HELD: return -EIO;
167         case NFS4ERR_OPENMODE: return -EIO;
168         case NFS4ERR_BADOWNER: return -EINVAL;
169         case NFS4ERR_BADCHAR: return -EINVAL;
170         case NFS4ERR_BADNAME: return -EINVAL;
171         case NFS4ERR_BAD_RANGE: return -EINVAL;
172         case NFS4ERR_LOCK_NOTSUPP: return -EINVAL;
173         case NFS4ERR_OP_ILLEGAL: return -EIO;
174         case NFS4ERR_DEADLOCK: return -EIO;
175         case NFS4ERR_FILE_OPEN: return -EIO;
176         case NFS4ERR_ADMIN_REVOKED: return -EIO;
177         case NFS4ERR_CB_PATH_DOWN: return -EIO;
178 	};
179 	return -ERANGE;
180 }
181 
182 int
rpc_nfs4_null_async(struct rpc_context * rpc,rpc_cb cb,void * private_data)183 rpc_nfs4_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data)
184 {
185 	struct rpc_pdu *pdu;
186 
187 	pdu = rpc_allocate_pdu(rpc, NFS4_PROGRAM, NFS_V4, NFSPROC4_NULL, cb,
188                                private_data, (zdrproc_t)zdr_void, 0);
189 	if (pdu == NULL) {
190 		rpc_set_error(rpc, "Out of memory. Failed to allocate pdu "
191                               "for NFS4/NULL call");
192 		return -1;
193 	}
194 
195 	if (rpc_queue_pdu(rpc, pdu) != 0) {
196 		rpc_set_error(rpc, "Out of memory. Failed to queue pdu for "
197                               "NFS4/NULL call");
198 		return -1;
199 	}
200 
201 	return 0;
202 }
203 
204 int
rpc_nfs4_compound_async(struct rpc_context * rpc,rpc_cb cb,struct COMPOUND4args * args,void * private_data)205 rpc_nfs4_compound_async(struct rpc_context *rpc, rpc_cb cb,
206                         struct COMPOUND4args *args, void *private_data)
207 {
208 	struct rpc_pdu *pdu;
209 
210 	pdu = rpc_allocate_pdu(rpc, NFS4_PROGRAM, NFS_V4, NFSPROC4_COMPOUND,
211                                cb, private_data, (zdrproc_t)zdr_COMPOUND4res,
212                                sizeof(COMPOUND4res));
213 	if (pdu == NULL) {
214 		rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for "
215                               "NFS4/COMPOUND call");
216 		return -1;
217 	}
218 
219 	if (zdr_COMPOUND4args(&pdu->zdr,  args) == 0) {
220 		rpc_set_error(rpc, "ZDR error: Failed to encode COMPOUND4args");
221 		rpc_free_pdu(rpc, pdu);
222 		return -2;
223 	}
224 
225 	if (rpc_queue_pdu(rpc, pdu) != 0) {
226 		rpc_set_error(rpc, "Out of memory. Failed to queue pdu for "
227                               "NFS4/COMPOUND4 call");
228 		return -3;
229 	}
230 
231 	return 0;
232 }
233