1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
24 */
25
26#include <smbsrv/smb_kproto.h>
27#include <smbsrv/smb_fsops.h>
28#include <smbsrv/smb_vops.h>
29
30int smb_open_dsize_check = 0;
31
32/*
33 *  Client Request                     Description
34 *  ================================== =================================
35 *
36 *  UCHAR WordCount;                   Count of parameter words = 15
37 *  UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
38 *                                      none
39 *  UCHAR AndXReserved;                Reserved (must be 0)
40 *  USHORT AndXOffset;                 Offset to next command WordCount
41 *  USHORT Flags;                      Additional information: bit set-
42 *                                      0 - return additional info
43 *                                      1 - exclusive oplock requested
44 *                                      2 - batch oplock requested
45 *  USHORT DesiredAccess;              File open mode
46 *  USHORT SearchAttributes;
47 *  USHORT FileAttributes;
48 *  UTIME CreationTime;                Creation timestamp for file if it
49 *                                      gets created
50 *  USHORT OpenFunction;               Action to take if file exists
51 *  ULONG AllocationSize;              Bytes to reserve on create or
52 *                                      truncate
53 *  ULONG Reserved[2];                 Must be 0
54 *  USHORT ByteCount;                  Count of data bytes;    min = 1
55 *  UCHAR BufferFormat                 0x04
56 *  STRING FileName;
57 *
58 *  Server Response                    Description
59 *  ================================== =================================
60 *
61 *  UCHAR WordCount;                   Count of parameter words = 15
62 *  UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
63 *                                      none
64 *  UCHAR AndXReserved;                Reserved (must be 0)
65 *  USHORT AndXOffset;                 Offset to next command WordCount
66 *  USHORT Fid;                        File handle
67 *  USHORT FileAttributes;
68 *  UTIME LastWriteTime;
69 *  ULONG DataSize;                    Current file size
70 *  USHORT GrantedAccess;              Access permissions actually
71 *                                      allowed
72 *  USHORT FileType;                   Type of file opened
73 *  USHORT DeviceState;                State of the named pipe
74 *  USHORT Action;                     Action taken
75 *  ULONG ServerFid;                   Server unique file id
76 *  USHORT Reserved;                   Reserved (must be 0)
77 *  USHORT ByteCount;                  Count of data bytes = 0
78 *
79 * DesiredAccess describes the access the client desires for the file (see
80 * section 3.6 -  Access Mode Encoding).
81 *
82 * OpenFunction specifies the action to be taken depending on whether or
83 * not the file exists (see section 3.8 -  Open Function Encoding).  Action
84 *
85 * in the response specifies the action as a result of the Open request
86 * (see section 3.9 -  Open Action Encoding).
87 *
88 * SearchAttributes indicates the attributes that the file must have to be
89 * found while searching to see if it exists.  The encoding of this field
90 * is described in the "File Attribute Encoding" section elsewhere in this
91 * document.  If SearchAttributes is zero then only normal files are
92 * returned.  If the system file, hidden or directory attributes are
93 * specified then the search is inclusive -- both the specified type(s) of
94 * files and normal files are returned.
95 *
96 * FileType returns the kind of resource actually opened:
97 *
98 *  Name                       Value  Description
99 *  ========================== ====== ==================================
100 *
101 *  FileTypeDisk               0      Disk file or directory as defined
102 *                                     in the attribute field
103 *  FileTypeByteModePipe       1      Named pipe in byte mode
104 *  FileTypeMessageModePipe    2      Named pipe in message mode
105 *  FileTypePrinter            3      Spooled printer
106 *  FileTypeUnknown            0xFFFF Unrecognized resource type
107 *
108 * If bit0 of Flags is clear, the FileAttributes, LastWriteTime, DataSize,
109 * FileType, and DeviceState have indeterminate values in the response.
110 *
111 * This SMB can request an oplock on the opened file.  Oplocks are fully
112 * described in the "Oplocks" section elsewhere in this document, and there
113 * is also discussion of oplocks in the SMB_COM_LOCKING_ANDX SMB
114 * description.  Bit1 and bit2 of the Flags field are used to request
115 * oplocks during open.
116 *
117 * The following SMBs may follow SMB_COM_OPEN_ANDX:
118 *
119 *    SMB_COM_READ    SMB_COM_READ_ANDX
120 *    SMB_COM_IOCTL
121 */
122
123/*
124 * This message is sent to obtain a file handle for a data file.  This
125 * returned Fid is used in subsequent client requests such as read, write,
126 * close, etc.
127 *
128 * Client Request                     Description
129 * ================================== =================================
130 *
131 * UCHAR WordCount;                   Count of parameter words = 2
132 * USHORT DesiredAccess;              Mode - read/write/share
133 * USHORT SearchAttributes;
134 * USHORT ByteCount;                  Count of data bytes;    min = 2
135 * UCHAR BufferFormat;                0x04
136 * STRING FileName[];                 File name
137 *
138 * FileName is the fully qualified file name, relative to the root of the
139 * share specified in the Tid field of the SMB header.  If Tid in the SMB
140 * header refers to a print share, this SMB creates a new file which will
141 * be spooled to the printer when closed.  In this case, FileName is
142 * ignored.
143 *
144 * SearchAttributes specifies the type of file desired.  The encoding is
145 * described in the "File Attribute Encoding" section.
146 *
147 * DesiredAccess controls the mode under which the file is opened, and the
148 * file will be opened only if the client has the appropriate permissions.
149 * The encoding of DesiredAccess is discussed in the section entitled
150 * "Access Mode Encoding".
151 *
152 * Server Response                    Description
153 * ================================== =================================
154 *
155 * UCHAR WordCount;                   Count of parameter words = 7
156 * USHORT Fid;                        File handle
157 * USHORT FileAttributes;             Attributes of opened file
158 * UTIME LastWriteTime;               Time file was last written
159 * ULONG DataSize;                    File size
160 * USHORT GrantedAccess;              Access allowed
161 * USHORT ByteCount;                  Count of data bytes = 0
162 *
163 * Fid is the handle value which should be used for subsequent file
164 * operations.
165 *
166 * FileAttributes specifies the type of file obtained.  The encoding is
167 * described in the "File Attribute Encoding" section.
168 *
169 * GrantedAccess indicates the access permissions actually allowed, and may
170 * have one of the following values:
171 *
172 *    0  read-only
173 *    1  write-only
174 *    2 read/write
175 *
176 * File Handles (Fids) are scoped per client.  A Pid may reference any Fid
177 * established by itself or any other Pid on the client (so far as the
178 * server is concerned).  The actual accesses allowed through the Fid
179 * depends on the open and deny modes specified when the file was opened
180 * (see below).
181 *
182 * The MS-DOS compatibility mode of file open provides exclusion at the
183 * client level.  A file open in compatibility mode may be opened (also in
184 * compatibility mode) any number of times for any combination of reading
185 * and writing (subject to the user's permissions) by any Pid on the same
186 * client.  If the first client has the file open for writing, then the
187 * file may not be opened in any way by any other client.  If the first
188 * client has the file open only for reading, then other clients may open
189 * the file, in compatibility mode, for reading..  The above
190 * notwithstanding, if the filename has an extension of .EXE, .DLL, .SYM,
191 * or .COM other clients are permitted to open the file regardless of
192 * read/write open modes of other compatibility mode opens.  However, once
193 * multiple clients have the file open for reading, no client is permitted
194 * to open the file for writing and no other client may open the file in
195 * any mode other than compatibility mode.
196 *
197 * The other file exclusion modes (Deny read/write, Deny write, Deny read,
198 * Deny none) provide exclusion at the file level.  A file opened in any
199 * "Deny" mode may be opened again only for the accesses allowed by the
200 * Deny mode (subject to the user's permissions).  This is true regardless
201 * of the identity of the second opener -a different client, a Pid from the
202 * same client, or the Pid that already has the file open.  For example, if
203 * a file is open in "Deny write" mode a second open may only obtain read
204 * permission to the file.
205 *
206 * Although Fids are available to all Pids on a client, Pids other than the
207 * owner may not have the full access rights specified in the open mode by
208 * the Fid's creator.  If the open creating the Fid specified a deny mode,
209 * then any Pid using the Fid, other than the creating Pid, will have only
210 * those access rights determined by "anding" the open mode rights and the
211 * deny mode rights, i.e., the deny mode is checked on all file accesses.
212 * For example, if a file is opened for Read/Write in Deny write mode, then
213 * other clients may only read the file and cannot write; if a file is
214 * opened for Read in Deny read mode, then the other clients can neither
215 * read nor write the file.
216 */
217
218smb_sdrc_t
219smb_pre_open(smb_request_t *sr)
220{
221	struct open_param *op = &sr->arg.open;
222	int rc;
223
224	bzero(op, sizeof (sr->arg.open));
225
226	rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
227	if (rc == 0)
228		rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
229
230	DTRACE_SMB_START(op__Open, smb_request_t *, sr); /* arg.open */
231
232	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
233}
234
235void
236smb_post_open(smb_request_t *sr)
237{
238	DTRACE_SMB_DONE(op__Open, smb_request_t *, sr);
239}
240
241smb_sdrc_t
242smb_com_open(smb_request_t *sr)
243{
244	struct open_param *op = &sr->arg.open;
245	smb_ofile_t *of;
246	uint32_t mtime_sec;
247	uint32_t status;
248	uint16_t file_attr;
249	int rc;
250
251	op->desired_access = smb_omode_to_amask(op->omode);
252	op->share_access = smb_denymode_to_sharemode(op->omode,
253	    op->fqi.fq_path.pn_path);
254	op->crtime.tv_sec = op->crtime.tv_nsec = 0;
255	op->create_disposition = FILE_OPEN;
256	op->create_options = FILE_NON_DIRECTORY_FILE;
257	if (op->omode & SMB_DA_WRITE_THROUGH)
258		op->create_options |= FILE_WRITE_THROUGH;
259
260	if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
261		if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
262			op->op_oplock_level = SMB_OPLOCK_BATCH;
263		else
264			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
265	} else {
266		op->op_oplock_level = SMB_OPLOCK_NONE;
267	}
268
269	if (smb_open_dsize_check && op->dsize > UINT_MAX) {
270		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
271		return (SDRC_ERROR);
272	}
273
274	/*
275	 * The real open call.   Note: this gets attributes into
276	 * op->fqi.fq_fattr (SMB_AT_ALL).  We need those below.
277	 */
278	status = smb_common_open(sr);
279	if (status != NT_STATUS_SUCCESS) {
280		smbsr_status(sr, status, 0, 0);
281		return (SDRC_ERROR);
282	}
283	if (op->op_oplock_level != SMB_OPLOCK_NONE) {
284		/* Oplock req. in op->op_oplock_level etc. */
285		smb1_oplock_acquire(sr, B_FALSE);
286	}
287
288	/*
289	 * NB: after the above smb_common_open() success,
290	 * we have a handle allocated (sr->fid_ofile).
291	 * If we don't return success, we must close it.
292	 */
293	of = sr->fid_ofile;
294
295	if (op->op_oplock_level == SMB_OPLOCK_NONE) {
296		sr->smb_flg &=
297		    ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
298	}
299
300	file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
301	mtime_sec = smb_time_gmt_to_local(sr,
302	    op->fqi.fq_fattr.sa_vattr.va_mtime.tv_sec);
303
304	rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
305	    7,
306	    sr->smb_fid,
307	    file_attr,
308	    mtime_sec,
309	    (uint32_t)op->dsize,
310	    op->omode,
311	    (uint16_t)0);	/* bcc */
312
313	if (rc == 0)
314		return (SDRC_SUCCESS);
315
316	smb_ofile_close(of, 0);
317	return (SDRC_ERROR);
318}
319
320int smb_openx_enable_extended_response = 1;
321
322/*
323 * smb_pre_open_andx
324 * For compatibility with windows servers, the search attributes
325 * specified in the request are ignored.
326 */
327smb_sdrc_t
328smb_pre_open_andx(smb_request_t *sr)
329{
330	struct open_param *op = &sr->arg.open;
331	uint16_t openx_flags;
332	uint32_t alloc_size;
333	uint32_t creation_time;
334	uint16_t file_attr, sattr;
335	int rc;
336
337	bzero(op, sizeof (sr->arg.open));
338
339	rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
340	    &sr->andx_off, &openx_flags, &op->omode, &sattr,
341	    &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
342
343	if (rc == 0) {
344		rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
345
346		op->dattr = file_attr;
347		op->dsize = alloc_size;
348
349		/*
350		 * The openx_flags use some "extended" flags that
351		 * happen to match some of the NtCreateX flags.
352		 */
353		if (openx_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
354			op->op_oplock_level = SMB_OPLOCK_BATCH;
355		else if (openx_flags & NT_CREATE_FLAG_REQUEST_OPLOCK)
356			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
357		else
358			op->op_oplock_level = SMB_OPLOCK_NONE;
359		if (openx_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE)
360			op->nt_flags |= NT_CREATE_FLAG_EXTENDED_RESPONSE;
361
362		if ((creation_time != 0) && (creation_time != UINT_MAX))
363			op->crtime.tv_sec =
364			    smb_time_local_to_gmt(sr, creation_time);
365		op->crtime.tv_nsec = 0;
366
367		op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
368	}
369
370	DTRACE_SMB_START(op__OpenX, smb_request_t *, sr); /* arg.open */
371
372	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
373}
374
375void
376smb_post_open_andx(smb_request_t *sr)
377{
378	DTRACE_SMB_DONE(op__OpenX, smb_request_t *, sr);
379}
380
381smb_sdrc_t
382smb_com_open_andx(smb_request_t *sr)
383{
384	struct open_param	*op = &sr->arg.open;
385	smb_attr_t		*ap = &op->fqi.fq_fattr;
386	smb_ofile_t		*of;
387	uint32_t		status;
388	uint32_t		mtime_sec;
389	uint16_t		file_attr;
390	int rc;
391
392	op->desired_access = smb_omode_to_amask(op->omode);
393	op->share_access = smb_denymode_to_sharemode(op->omode,
394	    op->fqi.fq_path.pn_path);
395
396	if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
397		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
398		return (SDRC_ERROR);
399	}
400
401	op->create_options = FILE_NON_DIRECTORY_FILE;
402	if (op->omode & SMB_DA_WRITE_THROUGH)
403		op->create_options |= FILE_WRITE_THROUGH;
404
405	if (smb_open_dsize_check && op->dsize > UINT_MAX) {
406		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
407		return (SDRC_ERROR);
408	}
409
410	status = smb_common_open(sr);
411	if (status != NT_STATUS_SUCCESS) {
412		smbsr_status(sr, status, 0, 0);
413		return (SDRC_ERROR);
414	}
415	if (op->op_oplock_level != SMB_OPLOCK_NONE) {
416		/* Oplock req. in op->op_oplock_level etc. */
417		smb1_oplock_acquire(sr, B_FALSE);
418	}
419
420	/*
421	 * NB: after the above smb_common_open() success,
422	 * we have a handle allocated (sr->fid_ofile).
423	 * If we don't return success, we must close it.
424	 */
425	of = sr->fid_ofile;
426
427	if (op->op_oplock_level != SMB_OPLOCK_NONE)
428		op->action_taken |= SMB_OACT_OPLOCK;
429	else
430		op->action_taken &= ~SMB_OACT_OPLOCK;
431
432	file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
433	mtime_sec = smb_time_gmt_to_local(sr, ap->sa_vattr.va_mtime.tv_sec);
434
435	switch (sr->tid_tree->t_res_type & STYPE_MASK) {
436	case STYPE_DISKTREE:
437	case STYPE_PRINTQ:
438		break;
439
440	case STYPE_IPC:
441		mtime_sec = 0;
442		break;
443
444	default:
445		smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
446		    ERRDOS, ERROR_INVALID_FUNCTION);
447		goto errout;
448	}
449
450	if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
451	    smb_openx_enable_extended_response != 0) {
452		uint32_t MaxAccess = 0;
453		if (of->f_node != NULL) {
454			smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
455		}
456		MaxAccess |= of->f_granted_access;
457
458		rc = smbsr_encode_result(
459		    sr, 19, 0, "bb.wwwllwwwwl2.llw",
460		    19,		/* word count	   (b) */
461		    sr->andx_com,		/* (b.) */
462		    VAR_BCC,	/* andx offset	   (w) */
463		    sr->smb_fid,		/* (w) */
464		    file_attr,			/* (w) */
465		    mtime_sec,			/* (l) */
466		    (uint32_t)op->dsize,	/* (l) */
467		    op->omode,			/* (w) */
468		    op->ftype,			/* (w) */
469		    op->devstate,		/* (w) */
470		    op->action_taken,		/* (w) */
471		    0,		/* legacy fileid   (l) */
472		    /* reserved			  (2.) */
473		    MaxAccess,			/* (l) */
474		    0,		/* guest access	   (l) */
475		    0);		/* byte count	   (w) */
476
477	} else {
478		rc = smbsr_encode_result(
479		    sr, 15, 0, "bb.wwwllwwwwl2.w",
480		    15,		/* word count	   (b) */
481		    sr->andx_com,		/* (b.) */
482		    VAR_BCC,	/* andx offset	   (w) */
483		    sr->smb_fid,		/* (w) */
484		    file_attr,			/* (w) */
485		    mtime_sec,			/* (l) */
486		    (uint32_t)op->dsize,	/* (l) */
487		    op->omode,			/* (w) */
488		    op->ftype,			/* (w) */
489		    op->devstate,		/* (w) */
490		    op->action_taken,		/* (w) */
491		    0,		/* legacy fileid   (l) */
492		    /* reserved			  (2.) */
493		    0);		/* byte count	   (w) */
494	}
495
496	if (rc == 0)
497		return (SDRC_SUCCESS);
498
499errout:
500	smb_ofile_close(of, 0);
501	return (SDRC_ERROR);
502}
503
504smb_sdrc_t
505smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
506{
507	struct open_param *op = &sr->arg.open;
508	uint32_t	creation_time;
509	uint32_t	alloc_size;
510	uint32_t	ea_list_size;
511	uint16_t	flags;
512	uint16_t	file_attr;
513	uint32_t	status;
514	int		rc;
515
516	bzero(op, sizeof (sr->arg.open));
517
518	rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
519	    sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
520	    &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
521	if (rc != 0)
522		return (SDRC_ERROR);
523
524	/*
525	 * The data part of this transaction may contain an EA list.
526	 * See: SMB_FEA_LIST ExtendedAttributeList
527	 *
528	 * If we find a non-empty EA list payload, return the special
529	 * error that tells the caller this FS does not suport EAs.
530	 *
531	 * Note: the first word is the size of the whole data segment,
532	 * INCLUDING the size of that length word.  That means if
533	 * the length word specifies a size less than four, it's
534	 * invalid (and probably a client trying something fishy).
535	 */
536	rc = smb_mbc_decodef(&xa->req_data_mb, "l", &ea_list_size);
537	if (rc == 0 && ea_list_size > 4) {
538		smbsr_status(sr, NT_STATUS_EAS_NOT_SUPPORTED, 0, 0);
539		return (SDRC_ERROR);
540	}
541
542	if ((creation_time != 0) && (creation_time != UINT_MAX))
543		op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
544	op->crtime.tv_nsec = 0;
545
546	op->dattr = file_attr;
547	op->dsize = alloc_size;
548	op->create_options = FILE_NON_DIRECTORY_FILE;
549
550	op->desired_access = smb_omode_to_amask(op->omode);
551	op->share_access = smb_denymode_to_sharemode(op->omode,
552	    op->fqi.fq_path.pn_path);
553
554	op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
555	if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
556		op->create_disposition = FILE_CREATE;
557
558	if (op->omode & SMB_DA_WRITE_THROUGH)
559		op->create_options |= FILE_WRITE_THROUGH;
560
561	if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
562		if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
563			op->op_oplock_level = SMB_OPLOCK_BATCH;
564		else
565			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
566	} else {
567		op->op_oplock_level = SMB_OPLOCK_NONE;
568	}
569
570	status = smb_common_open(sr);
571	if (status != NT_STATUS_SUCCESS) {
572		smbsr_status(sr, status, 0, 0);
573		return (SDRC_ERROR);
574	}
575	if (op->op_oplock_level != SMB_OPLOCK_NONE) {
576		/* Oplock req. in op->op_oplock_level etc. */
577		smb1_oplock_acquire(sr, B_FALSE);
578	}
579
580	if (op->op_oplock_level != SMB_OPLOCK_NONE)
581		op->action_taken |= SMB_OACT_OPLOCK;
582	else
583		op->action_taken &= ~SMB_OACT_OPLOCK;
584
585	file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
586
587	if (STYPE_ISIPC(sr->tid_tree->t_res_type))
588		op->dsize = 0;
589
590	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
591	    sr->smb_fid,
592	    file_attr,
593	    (uint32_t)0,	/* creation time */
594	    (uint32_t)op->dsize,
595	    op->omode,
596	    op->ftype,
597	    op->devstate,
598	    op->action_taken,
599	    op->fileid,
600	    (uint16_t)0,	/* EA error offset */
601	    (uint32_t)0);	/* EA list length */
602
603	return (SDRC_SUCCESS);
604}
605