147 } |
147 } |
148 return (TRUE); |
148 return (TRUE); |
149 } |
149 } |
150 |
150 |
151 /* |
151 /* |
152 * Called in nfs_acl_xdr.c |
152 * XDR_INLINE encode a filehandle. |
|
153 */ |
|
154 bool_t |
|
155 xdr_inline_encode_nfs_fh4(uint32_t **ptrp, uint32_t *ptr_redzone, |
|
156 nfs_fh4_fmt_t *fhp) |
|
157 { |
|
158 uint32_t *ptr = *ptrp; |
|
159 uint_t otw_len; |
|
160 char *curp; |
|
161 uint_t dlen; |
|
162 uint32_t padword; |
|
163 |
|
164 /* |
|
165 * First get the variable sized part of the filehandle. |
|
166 */ |
|
167 otw_len = fhp->fh4_len + fhp->fh4_xlen + sizeof (fhp->fh4_fsid) + |
|
168 sizeof (fhp->fh4_len) + sizeof (fhp->fh4_xlen); |
|
169 /* |
|
170 * Round out to a full word. |
|
171 */ |
|
172 otw_len = RNDUP(otw_len); |
|
173 padword = (otw_len / BYTES_PER_XDR_UNIT) - 1; |
|
174 |
|
175 /* |
|
176 * Add in the fixed sized pieces. |
|
177 */ |
|
178 otw_len += sizeof (fhp->fh4_flag); |
|
179 |
|
180 #ifdef VOLATILE_FH_TEST |
|
181 otw_len += sizeof (fhp->fh4_volatile_id); |
|
182 #endif |
|
183 |
|
184 /* |
|
185 * Make sure we don't exceed our buffer. |
|
186 */ |
|
187 if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone) |
|
188 return (FALSE); |
|
189 |
|
190 IXDR_PUT_U_INT32(ptr, otw_len); |
|
191 |
|
192 /* |
|
193 * Zero out the pading. |
|
194 */ |
|
195 ptr[padword] = 0; |
|
196 |
|
197 /* fh4_fsid */ |
|
198 IXDR_PUT_INT32(ptr, fhp->fh4_fsid.val[0]); |
|
199 IXDR_PUT_INT32(ptr, fhp->fh4_fsid.val[1]); |
|
200 |
|
201 /* |
|
202 * Since the next pieces are unaligned, we need to |
|
203 * do bytewise copies. |
|
204 */ |
|
205 curp = (char *)ptr; |
|
206 |
|
207 /* fh4_len + fh4_data */ |
|
208 dlen = sizeof (fhp->fh4_len); |
|
209 dlen += fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len; |
|
210 bcopy(&fhp->fh4_len, curp, dlen); |
|
211 curp += dlen; |
|
212 |
|
213 /* fh4_xlen + fh4_xdata */ |
|
214 dlen = sizeof (fhp->fh4_xlen); |
|
215 dlen += fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen; |
|
216 bcopy(&fhp->fh4_xlen, curp, dlen); |
|
217 curp += dlen; |
|
218 |
|
219 /* do necessary rounding/padding */ |
|
220 curp = (char *)RNDUP((uintptr_t)curp); |
|
221 ptr = (uint32_t *)curp; |
|
222 |
|
223 /* |
|
224 * With the above padding, we're word aligned again. |
|
225 */ |
|
226 ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0); |
|
227 |
|
228 /* fh4_flag */ |
|
229 IXDR_PUT_INT32(ptr, fhp->fh4_flag); |
|
230 |
|
231 #ifdef VOLATILE_FH_TEST |
|
232 /* fh4_volatile_id */ |
|
233 IXDR_PUT_INT32(ptr, fhp->fh4_volatile_id); |
|
234 #endif |
|
235 *ptrp = ptr; |
|
236 |
|
237 return (TRUE); |
|
238 } |
|
239 |
|
240 static char xdr_crud[BYTES_PER_XDR_UNIT]; |
|
241 |
|
242 static bool_t |
|
243 xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp) |
|
244 { |
|
245 uint32_t fhsize; /* filehandle size */ |
|
246 uint32_t fsize; /* fh_len size */ |
|
247 uint32_t xsize; /* fh_xlen size */ |
|
248 uint32_t rsize; /* bytes to round */ |
|
249 uint32_t psize; /* pad size */ |
|
250 uint32_t dsize; /* "data" size */ |
|
251 nfs_fh4_fmt_t *fh_fmtp; |
|
252 |
|
253 ASSERT(xdrs->x_op == XDR_DECODE); |
|
254 |
|
255 /* |
|
256 * Retrieve the filehandle length. |
|
257 */ |
|
258 if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize)) |
|
259 return (FALSE); |
|
260 |
|
261 /* |
|
262 * Check to see if what the client sent us is bigger than what |
|
263 * we can ever possibly send out or smaller than what we could |
|
264 * possibly send out. |
|
265 */ |
|
266 if (fhsize > sizeof (nfs_fh4_fmt_t) || |
|
267 fhsize < sizeof (fsid_t) + sizeof (ushort_t) + sizeof (ushort_t)) |
|
268 return (FALSE); |
|
269 |
|
270 rsize = fhsize % BYTES_PER_XDR_UNIT; |
|
271 if (rsize != 0) |
|
272 rsize = BYTES_PER_XDR_UNIT - rsize; |
|
273 |
|
274 objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP); |
|
275 objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t); |
|
276 fh_fmtp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val; |
|
277 |
|
278 /* |
|
279 * Decode what should be fh4_fsid. |
|
280 */ |
|
281 if (!XDR_GETINT32(xdrs, (int32_t *)&fh_fmtp->fh4_fsid.val[0])) |
|
282 return (FALSE); |
|
283 if (!XDR_GETINT32(xdrs, (int32_t *)&fh_fmtp->fh4_fsid.val[1])) |
|
284 return (FALSE); |
|
285 fhsize -= sizeof (fsid_t); |
|
286 |
|
287 /* |
|
288 * Decode what should be fh4_len. fh4_len is two bytes, so we're |
|
289 * unaligned now, have to use XDR_GETBYTES from now on. |
|
290 */ |
|
291 if (!XDR_GETBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_len, |
|
292 sizeof (ushort_t))) |
|
293 return (FALSE); |
|
294 fhsize -= sizeof (ushort_t); |
|
295 |
|
296 fsize = fh_fmtp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : |
|
297 fh_fmtp->fh4_len; |
|
298 /* |
|
299 * Make sure the client isn't sending us a bogus length for fh4_data. |
|
300 */ |
|
301 if (fhsize < fsize) |
|
302 return (FALSE); |
|
303 |
|
304 if (!XDR_GETBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_data, fsize)) |
|
305 return (FALSE); |
|
306 fhsize -= fsize; |
|
307 |
|
308 /* make sure we have enough left to decode fh_xlen */ |
|
309 if (fhsize < sizeof (ushort_t)) |
|
310 return (FALSE); |
|
311 |
|
312 if (!XDR_GETBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_xlen, |
|
313 sizeof (ushort_t))) |
|
314 return (FALSE); |
|
315 fhsize -= sizeof (ushort_t); |
|
316 |
|
317 xsize = fh_fmtp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : |
|
318 fh_fmtp->fh4_xlen; |
|
319 /* |
|
320 * Make sure the client isn't sending us a bogus length for fh4_xdata. |
|
321 */ |
|
322 if (fhsize < xsize) |
|
323 return (FALSE); |
|
324 |
|
325 if (!XDR_GETBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_xdata, xsize)) |
|
326 return (FALSE); |
|
327 fhsize -= xsize; |
|
328 |
|
329 /* we purposedly align things, so skip padding */ |
|
330 dsize = fsize + xsize + sizeof (ushort_t) + sizeof (ushort_t); |
|
331 psize = RNDUP(dsize); |
|
332 if (psize != dsize) |
|
333 if (!XDR_GETBYTES(xdrs, (caddr_t)&xdr_crud, psize - dsize)) |
|
334 return (FALSE); |
|
335 |
|
336 /* make sure we have enough left to decode fh4_flag */ |
|
337 if (fhsize < sizeof (uint32_t)) |
|
338 return (FALSE); |
|
339 |
|
340 if (!XDR_GETBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_flag, |
|
341 sizeof (uint32_t))) |
|
342 return (FALSE); |
|
343 fhsize -= sizeof (uint32_t); |
|
344 |
|
345 #ifdef VOLATILE_FH_TEST |
|
346 /* make sure we have enough left to decode fh4_volatile_id */ |
|
347 if (fhsize < sizeof (uint32_t)) |
|
348 return (FALSE); |
|
349 |
|
350 if (!XDR_GETBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_volatile_id, |
|
351 sizeof (uint32_t))) |
|
352 return (FALSE); |
|
353 fhsize -= sizeof (uint32_t); |
|
354 #endif |
|
355 /* |
|
356 * Make sure client didn't send request with too much padding. |
|
357 */ |
|
358 if (fhsize > sizeof (uint32_t)) |
|
359 return (FALSE); |
|
360 |
|
361 if (rsize) |
|
362 if (!XDR_GETBYTES(xdrs, (caddr_t)&xdr_crud, rsize)) |
|
363 return (FALSE); |
|
364 |
|
365 return (TRUE); |
|
366 } |
|
367 |
|
368 static char zero_word[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; |
|
369 |
|
370 static bool_t |
|
371 xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp) |
|
372 { |
|
373 uint_t otwsize, fsize, xsize; /* otw, file, and export sizes */ |
|
374 uint_t dsize, rsize; /* rounding sizes */ |
|
375 nfs_fh4_fmt_t *fh_fmtp; |
|
376 |
|
377 ASSERT(xdrs->x_op == XDR_ENCODE); |
|
378 |
|
379 fh_fmtp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val; |
|
380 fsize = fh_fmtp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : |
|
381 fh_fmtp->fh4_len; |
|
382 xsize = fh_fmtp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : |
|
383 fh_fmtp->fh4_xlen; |
|
384 /* fh4_i */ |
|
385 otwsize = sizeof (fsid_t) + sizeof (ushort_t) + fsize + |
|
386 sizeof (ushort_t) + xsize; |
|
387 |
|
388 /* round out to a full word */ |
|
389 otwsize = RNDUP(otwsize); |
|
390 |
|
391 /* fh4_flag */ |
|
392 otwsize += sizeof (uint32_t); |
|
393 |
|
394 #ifdef VOLATILE_FH_TEST |
|
395 /* fh4_volatile_id */ |
|
396 otwsize += sizeof (uint32_t); |
|
397 #endif |
|
398 |
|
399 /* |
|
400 * XDR in filehandle size. |
|
401 */ |
|
402 if (!XDR_PUTINT32(xdrs, (int32_t *)&otwsize)) |
|
403 return (FALSE); |
|
404 |
|
405 if (!XDR_PUTINT32(xdrs, (int32_t *)&fh_fmtp->fh4_fsid.val[0])) |
|
406 return (FALSE); |
|
407 if (!XDR_PUTINT32(xdrs, (int32_t *)&fh_fmtp->fh4_fsid.val[1])) |
|
408 return (FALSE); |
|
409 |
|
410 if (!XDR_PUTBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_len, fsize + |
|
411 sizeof (ushort_t))) |
|
412 return (FALSE); |
|
413 |
|
414 if (!XDR_PUTBYTES(xdrs, (caddr_t)&fh_fmtp->fh4_xlen, xsize + |
|
415 sizeof (ushort_t))) |
|
416 return (FALSE); |
|
417 |
|
418 dsize = fsize + xsize + sizeof (ushort_t) + sizeof (ushort_t); |
|
419 rsize = RNDUP(dsize); |
|
420 |
|
421 /* |
|
422 * Pad in the extra space to force alignment. |
|
423 */ |
|
424 if (dsize != rsize) |
|
425 if (!XDR_PUTBYTES(xdrs, (caddr_t)&zero_word, rsize - dsize)) |
|
426 return (FALSE); |
|
427 |
|
428 if (!XDR_PUTINT32(xdrs, (int32_t *)&fh_fmtp->fh4_flag)) |
|
429 return (FALSE); |
|
430 |
|
431 #ifdef VOLATILE_FH_TEST |
|
432 if (!XDR_PUTINT32(xdrs, (int32_t *)&fh_fmtp->fh4_volatile_id)) |
|
433 return (FALSE); |
|
434 #endif |
|
435 |
|
436 return (TRUE); |
|
437 } |
|
438 |
|
439 /* |
|
440 * XDR a NFSv4 filehandle. |
153 */ |
441 */ |
154 bool_t |
442 bool_t |
155 xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp) |
443 xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp) |
156 { |
444 { |
157 if (xdrs->x_op != XDR_FREE) |
445 if (xdrs->x_op == XDR_DECODE) |
158 return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val, |
446 return (xdr_decode_nfs_fh4(xdrs, objp)); |
159 (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE)); |
447 else if (xdrs->x_op == XDR_ENCODE) |
|
448 return (xdr_encode_nfs_fh4(xdrs, objp)); |
160 |
449 |
161 if (objp->nfs_fh4_val != NULL) { |
450 if (objp->nfs_fh4_val != NULL) { |
162 kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len); |
451 kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len); |
163 objp->nfs_fh4_val = NULL; |
452 objp->nfs_fh4_val = NULL; |
164 } |
453 } |
4258 (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, |
4601 (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, |
4259 sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4)); |
4602 sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4)); |
4260 } |
4603 } |
4261 |
4604 |
4262 bool_t |
4605 bool_t |
4263 xdr_COMPOUND4args(XDR *xdrs, COMPOUND4args *objp) |
4606 xdr_COMPOUND4args_srv(XDR *xdrs, COMPOUND4args *objp) |
4264 { |
4607 { |
4265 if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val, |
4608 if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val, |
4266 (uint_t *)&objp->tag.utf8string_len, |
4609 (uint_t *)&objp->tag.utf8string_len, |
4267 NFS4_MAX_UTF8STRING)) |
4610 NFS4_MAX_UTF8STRING)) |
4268 return (FALSE); |
4611 return (FALSE); |
4269 if (!xdr_u_int(xdrs, &objp->minorversion)) |
4612 if (!xdr_u_int(xdrs, &objp->minorversion)) |
4270 return (FALSE); |
4613 return (FALSE); |
4271 if (xdrs->x_op != XDR_FREE) |
4614 if (xdrs->x_op != XDR_FREE) |
4272 return (xdr_array(xdrs, (char **)&objp->array, |
4615 return (xdr_array(xdrs, (char **)&objp->array, |
4273 (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, |
4616 (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, |
4274 sizeof (nfs_argop4), (xdrproc_t)xdr_nfs_argop4)); |
4617 sizeof (nfs_argop4), (xdrproc_t)xdr_snfs_argop4)); |
4275 |
4618 |
4276 return (xdr_nfs_argop4_free(xdrs, &objp->array, objp->array_len)); |
4619 return (xdr_snfs_argop4_free(xdrs, &objp->array, objp->array_len)); |
4277 } |
4620 } |
4278 |
4621 |
4279 bool_t |
4622 bool_t |
4280 xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp) |
4623 xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp) |
4281 { |
4624 { |