xref: /illumos-gate/usr/src/cmd/fs.d/ufs/fsck/pass3b.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
8*7c478bd9Sstevel@tonic-gate 
9*7c478bd9Sstevel@tonic-gate /*
10*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
11*7c478bd9Sstevel@tonic-gate  * All rights reserved.
12*7c478bd9Sstevel@tonic-gate  *
13*7c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
14*7c478bd9Sstevel@tonic-gate  * provided that: (1) source distributions retain this entire copyright
15*7c478bd9Sstevel@tonic-gate  * notice and comment, and (2) distributions including binaries display
16*7c478bd9Sstevel@tonic-gate  * the following acknowledgement:  ``This product includes software
17*7c478bd9Sstevel@tonic-gate  * developed by the University of California, Berkeley and its contributors''
18*7c478bd9Sstevel@tonic-gate  * in the documentation or other materials provided with the distribution
19*7c478bd9Sstevel@tonic-gate  * and in all advertising materials mentioning features or use of this
20*7c478bd9Sstevel@tonic-gate  * software. Neither the name of the University nor the names of its
21*7c478bd9Sstevel@tonic-gate  * contributors may be used to endorse or promote products derived
22*7c478bd9Sstevel@tonic-gate  * from this software without specific prior written permission.
23*7c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24*7c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25*7c478bd9Sstevel@tonic-gate  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26*7c478bd9Sstevel@tonic-gate  */
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #include <stdio.h>
31*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/mntent.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/acl.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_acl.h>
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #define	bcopy(f, t, n)	memcpy(t, f, n)
39*7c478bd9Sstevel@tonic-gate #define	bzero(s, n)	memset(s, 0, n)
40*7c478bd9Sstevel@tonic-gate #define	bcmp(s, d, n)	memcmp(s, d, n)
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate #define	index(s, r)	strchr(s, r)
43*7c478bd9Sstevel@tonic-gate #define	rindex(s, r)	strrchr(s, r)
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
47*7c478bd9Sstevel@tonic-gate #include <string.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_inode.h>
49*7c478bd9Sstevel@tonic-gate #include "fsck.h"
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate int pass3bcheck(struct inodesc *);
52*7c478bd9Sstevel@tonic-gate int aclblksort();
53*7c478bd9Sstevel@tonic-gate void dodump(char *, int);
54*7c478bd9Sstevel@tonic-gate int bufchk(char *, int64_t);
55*7c478bd9Sstevel@tonic-gate void listshadows(void);
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate pass3b()
58*7c478bd9Sstevel@tonic-gate {
59*7c478bd9Sstevel@tonic-gate 	ino_t inumber;
60*7c478bd9Sstevel@tonic-gate 	struct dinode *dp;
61*7c478bd9Sstevel@tonic-gate 	struct aclinfo *aclp;
62*7c478bd9Sstevel@tonic-gate 	struct inodesc curino;
63*7c478bd9Sstevel@tonic-gate 	char pathbuf[MAXPATHLEN + 1];
64*7c478bd9Sstevel@tonic-gate 	int64_t maxaclsize = 0;
65*7c478bd9Sstevel@tonic-gate 	struct shadowclientinfo *sci;
66*7c478bd9Sstevel@tonic-gate 	struct shadowclients *scc;
67*7c478bd9Sstevel@tonic-gate 	int i;
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 	/*
70*7c478bd9Sstevel@tonic-gate 	 * Sort the acl list into disk block order.
71*7c478bd9Sstevel@tonic-gate 	 */
72*7c478bd9Sstevel@tonic-gate 	qsort((char *)aclpsort, (int)aclplast, sizeof (*aclpsort), aclblksort);
73*7c478bd9Sstevel@tonic-gate 	/*
74*7c478bd9Sstevel@tonic-gate 	 * Scan all the acl inodes, finding the largest acl file.
75*7c478bd9Sstevel@tonic-gate 	 */
76*7c478bd9Sstevel@tonic-gate 	for (inumber = 0; inumber < aclplast; inumber++) {
77*7c478bd9Sstevel@tonic-gate 		aclp = aclpsort[inumber];
78*7c478bd9Sstevel@tonic-gate 		/* ACL file will not be >=2GB */
79*7c478bd9Sstevel@tonic-gate 		if ((int64_t)aclp->i_isize > maxaclsize)
80*7c478bd9Sstevel@tonic-gate 			maxaclsize = (int64_t)aclp->i_isize;
81*7c478bd9Sstevel@tonic-gate 	}
82*7c478bd9Sstevel@tonic-gate 	maxaclsize = ((maxaclsize / sblock.fs_bsize) + 1) *
83*7c478bd9Sstevel@tonic-gate 				sblock.fs_bsize;
84*7c478bd9Sstevel@tonic-gate 	if ((aclbuf = malloc(maxaclsize)) == NULL) {
85*7c478bd9Sstevel@tonic-gate 		printf("cannot alloc %ld bytes for aclbuf\n", maxaclsize);
86*7c478bd9Sstevel@tonic-gate 		return (1);
87*7c478bd9Sstevel@tonic-gate 	}
88*7c478bd9Sstevel@tonic-gate 	/*
89*7c478bd9Sstevel@tonic-gate 	 * Scan all the acl inodes, checking contents
90*7c478bd9Sstevel@tonic-gate 	 */
91*7c478bd9Sstevel@tonic-gate 	for (inumber = 0; inumber < aclplast; inumber++) {
92*7c478bd9Sstevel@tonic-gate 		aclp = aclpsort[inumber];
93*7c478bd9Sstevel@tonic-gate 		dp = ginode(aclp->i_number);
94*7c478bd9Sstevel@tonic-gate 		curino.id_fix = FIX;
95*7c478bd9Sstevel@tonic-gate 		curino.id_type = ACL;
96*7c478bd9Sstevel@tonic-gate 		curino.id_func = pass3bcheck;
97*7c478bd9Sstevel@tonic-gate 		curino.id_number = aclp->i_number;
98*7c478bd9Sstevel@tonic-gate 		curino.id_filesize = aclp->i_isize;
99*7c478bd9Sstevel@tonic-gate 		aclbufoff = 0;
100*7c478bd9Sstevel@tonic-gate 		bzero(aclbuf, (size_t)maxaclsize);
101*7c478bd9Sstevel@tonic-gate 		if ((ckinode(dp, &curino) & KEEPON) == 0 ||
102*7c478bd9Sstevel@tonic-gate 				bufchk(aclbuf, (int64_t)aclp->i_isize)) {
103*7c478bd9Sstevel@tonic-gate 			if (dp->di_nlink <= 0) {
104*7c478bd9Sstevel@tonic-gate 				statemap[aclp->i_number] = FSTATE;
105*7c478bd9Sstevel@tonic-gate 				continue;
106*7c478bd9Sstevel@tonic-gate 			}
107*7c478bd9Sstevel@tonic-gate 			printf("ACL I=%d BAD/CORRUPT", aclp->i_number);
108*7c478bd9Sstevel@tonic-gate 			if (preen || reply("CLEAR") == 1) {
109*7c478bd9Sstevel@tonic-gate 				if (preen)
110*7c478bd9Sstevel@tonic-gate 					printf("\n");
111*7c478bd9Sstevel@tonic-gate 				freeino(aclp->i_number);
112*7c478bd9Sstevel@tonic-gate 			}
113*7c478bd9Sstevel@tonic-gate 		}
114*7c478bd9Sstevel@tonic-gate 	}
115*7c478bd9Sstevel@tonic-gate 	/*
116*7c478bd9Sstevel@tonic-gate 	 * Now scan all shadow inodes, checking that any inodes that previously
117*7c478bd9Sstevel@tonic-gate 	 * had an acl still have an acl.
118*7c478bd9Sstevel@tonic-gate 	 */
119*7c478bd9Sstevel@tonic-gate 	for (sci = shadowclientinfo; sci; sci = sci->next) {
120*7c478bd9Sstevel@tonic-gate 		if (statemap[sci->shadow] != SSTATE) {
121*7c478bd9Sstevel@tonic-gate 			for (scc = sci->clients; scc; scc = scc->next) {
122*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < scc->nclients; i++) {
123*7c478bd9Sstevel@tonic-gate 					printf("I=%d HAS BAD/CLEARED ACL I=%d",
124*7c478bd9Sstevel@tonic-gate 					    scc->client[i], sci->shadow);
125*7c478bd9Sstevel@tonic-gate 					if (preen || reply("FIX") == 1) {
126*7c478bd9Sstevel@tonic-gate 						if (preen)
127*7c478bd9Sstevel@tonic-gate 							printf("\n");
128*7c478bd9Sstevel@tonic-gate 						dp = ginode(scc->client[i]);
129*7c478bd9Sstevel@tonic-gate 						dp->di_mode &= IFMT;
130*7c478bd9Sstevel@tonic-gate 						dp->di_smode = dp->di_mode;
131*7c478bd9Sstevel@tonic-gate 						/*
132*7c478bd9Sstevel@tonic-gate 						 * Decrement link count -
133*7c478bd9Sstevel@tonic-gate 						 * pass1 made sure the shadow
134*7c478bd9Sstevel@tonic-gate 						 * inode # is a valid inode
135*7c478bd9Sstevel@tonic-gate 						 * number.
136*7c478bd9Sstevel@tonic-gate 						 */
137*7c478bd9Sstevel@tonic-gate 						lncntp[dp->di_shadow]++;
138*7c478bd9Sstevel@tonic-gate 						dp->di_shadow = 0;
139*7c478bd9Sstevel@tonic-gate 						inodirty();
140*7c478bd9Sstevel@tonic-gate 					}
141*7c478bd9Sstevel@tonic-gate 				}
142*7c478bd9Sstevel@tonic-gate 			}
143*7c478bd9Sstevel@tonic-gate 		}
144*7c478bd9Sstevel@tonic-gate 	}
145*7c478bd9Sstevel@tonic-gate 	/* listshadows(); */
146*7c478bd9Sstevel@tonic-gate }
147*7c478bd9Sstevel@tonic-gate 
148*7c478bd9Sstevel@tonic-gate /*
149*7c478bd9Sstevel@tonic-gate  * Collect all the (data) blocks of an acl file into a buffer.
150*7c478bd9Sstevel@tonic-gate  * Later we'll scan the buffer and validate the acl data.
151*7c478bd9Sstevel@tonic-gate  */
152*7c478bd9Sstevel@tonic-gate int
153*7c478bd9Sstevel@tonic-gate pass3bcheck(struct inodesc *idesc)
154*7c478bd9Sstevel@tonic-gate {
155*7c478bd9Sstevel@tonic-gate 	struct bufarea *bp;
156*7c478bd9Sstevel@tonic-gate 	int size, bsize;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate 	if (aclbufoff == idesc->id_filesize) {
159*7c478bd9Sstevel@tonic-gate 		return (STOP);
160*7c478bd9Sstevel@tonic-gate 	}
161*7c478bd9Sstevel@tonic-gate 	bsize = size = sblock.fs_fsize * idesc->id_numfrags;
162*7c478bd9Sstevel@tonic-gate 	if ((size + aclbufoff) > idesc->id_filesize)
163*7c478bd9Sstevel@tonic-gate 		size = idesc->id_filesize - aclbufoff;
164*7c478bd9Sstevel@tonic-gate 	bp = getdatablk(idesc->id_blkno, bsize);
165*7c478bd9Sstevel@tonic-gate 	bcopy(bp->b_un.b_buf, aclbuf + aclbufoff, (size_t)size);
166*7c478bd9Sstevel@tonic-gate 	aclbufoff += size;
167*7c478bd9Sstevel@tonic-gate 	brelse(bp);
168*7c478bd9Sstevel@tonic-gate 	return (KEEPON);
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate /*
172*7c478bd9Sstevel@tonic-gate  * Routine to sort disk blocks.
173*7c478bd9Sstevel@tonic-gate  */
174*7c478bd9Sstevel@tonic-gate aclblksort(aclpp1, aclpp2)
175*7c478bd9Sstevel@tonic-gate 	struct aclinfo **aclpp1, **aclpp2;
176*7c478bd9Sstevel@tonic-gate {
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	return ((*aclpp1)->i_blks[0] - (*aclpp2)->i_blks[0]);
179*7c478bd9Sstevel@tonic-gate }
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate int
182*7c478bd9Sstevel@tonic-gate bufchk(char *buf, int64_t len)
183*7c478bd9Sstevel@tonic-gate {
184*7c478bd9Sstevel@tonic-gate 	ufs_fsd_t *fsdp;
185*7c478bd9Sstevel@tonic-gate 	ufs_acl_t *ufsaclp = NULL;
186*7c478bd9Sstevel@tonic-gate 	int numacls;
187*7c478bd9Sstevel@tonic-gate 	int i;
188*7c478bd9Sstevel@tonic-gate 	int nuser_objs = 0;
189*7c478bd9Sstevel@tonic-gate 	int ngroup_objs = 0;
190*7c478bd9Sstevel@tonic-gate 	int nother_objs = 0;
191*7c478bd9Sstevel@tonic-gate 	int nclass_objs = 0;
192*7c478bd9Sstevel@tonic-gate 	int ndef_user_objs = 0;
193*7c478bd9Sstevel@tonic-gate 	int ndef_group_objs = 0;
194*7c478bd9Sstevel@tonic-gate 	int ndef_other_objs = 0;
195*7c478bd9Sstevel@tonic-gate 	int ndef_class_objs = 0;
196*7c478bd9Sstevel@tonic-gate 	int nusers = 0;
197*7c478bd9Sstevel@tonic-gate 	int ngroups = 0;
198*7c478bd9Sstevel@tonic-gate 	int ndef_users = 0;
199*7c478bd9Sstevel@tonic-gate 	int ndef_groups = 0;
200*7c478bd9Sstevel@tonic-gate 	int numdefs = 0;
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 	for (fsdp = (ufs_fsd_t *)buf;
203*7c478bd9Sstevel@tonic-gate 	    (caddr_t)fsdp < (buf + len) &&
204*7c478bd9Sstevel@tonic-gate 	    ((caddr_t)fsdp + fsdp->fsd_size) <= (buf + len);
205*7c478bd9Sstevel@tonic-gate 	    fsdp = (ufs_fsd_t *)((caddr_t)fsdp +
206*7c478bd9Sstevel@tonic-gate 	    FSD_RECSZ(fsdp, fsdp->fsd_size))) {
207*7c478bd9Sstevel@tonic-gate 		switch (fsdp->fsd_type) {
208*7c478bd9Sstevel@tonic-gate 		case FSD_ACL:
209*7c478bd9Sstevel@tonic-gate 		case FSD_DFACL:
210*7c478bd9Sstevel@tonic-gate 			numacls = (fsdp->fsd_size - 2 * sizeof (int)) /
211*7c478bd9Sstevel@tonic-gate 							sizeof (ufs_acl_t);
212*7c478bd9Sstevel@tonic-gate 			for (ufsaclp = (ufs_acl_t *)fsdp->fsd_data;
213*7c478bd9Sstevel@tonic-gate 							numacls; ufsaclp++) {
214*7c478bd9Sstevel@tonic-gate 				switch (ufsaclp->acl_tag) {
215*7c478bd9Sstevel@tonic-gate 				case USER_OBJ:		/* Owner */
216*7c478bd9Sstevel@tonic-gate 					nuser_objs++;
217*7c478bd9Sstevel@tonic-gate 					break;
218*7c478bd9Sstevel@tonic-gate 				case GROUP_OBJ:		/* Group */
219*7c478bd9Sstevel@tonic-gate 					ngroup_objs++;
220*7c478bd9Sstevel@tonic-gate 					break;
221*7c478bd9Sstevel@tonic-gate 				case OTHER_OBJ:		/* Other */
222*7c478bd9Sstevel@tonic-gate 					nother_objs++;
223*7c478bd9Sstevel@tonic-gate 					break;
224*7c478bd9Sstevel@tonic-gate 				case CLASS_OBJ:		/* Mask */
225*7c478bd9Sstevel@tonic-gate 					nclass_objs++;
226*7c478bd9Sstevel@tonic-gate 					break;
227*7c478bd9Sstevel@tonic-gate 				case DEF_USER_OBJ:	/* Default Owner */
228*7c478bd9Sstevel@tonic-gate 					ndef_user_objs++;
229*7c478bd9Sstevel@tonic-gate 					break;
230*7c478bd9Sstevel@tonic-gate 				case DEF_GROUP_OBJ:	/* Default Group */
231*7c478bd9Sstevel@tonic-gate 					ndef_group_objs++;
232*7c478bd9Sstevel@tonic-gate 					break;
233*7c478bd9Sstevel@tonic-gate 				case DEF_OTHER_OBJ:	/* Default Other */
234*7c478bd9Sstevel@tonic-gate 					ndef_other_objs++;
235*7c478bd9Sstevel@tonic-gate 					break;
236*7c478bd9Sstevel@tonic-gate 				case DEF_CLASS_OBJ:	/* Default Mask */
237*7c478bd9Sstevel@tonic-gate 					ndef_class_objs++;
238*7c478bd9Sstevel@tonic-gate 					break;
239*7c478bd9Sstevel@tonic-gate 				case USER:		/* Users */
240*7c478bd9Sstevel@tonic-gate 					nusers++;
241*7c478bd9Sstevel@tonic-gate 					break;
242*7c478bd9Sstevel@tonic-gate 				case GROUP:		/* Groups */
243*7c478bd9Sstevel@tonic-gate 					ngroups++;
244*7c478bd9Sstevel@tonic-gate 					break;
245*7c478bd9Sstevel@tonic-gate 				case DEF_USER:		/* Default Users */
246*7c478bd9Sstevel@tonic-gate 					ndef_users++;
247*7c478bd9Sstevel@tonic-gate 					break;
248*7c478bd9Sstevel@tonic-gate 				case DEF_GROUP:		/* Default Groups */
249*7c478bd9Sstevel@tonic-gate 					ndef_groups++;
250*7c478bd9Sstevel@tonic-gate 					break;
251*7c478bd9Sstevel@tonic-gate 				default:
252*7c478bd9Sstevel@tonic-gate 					return (1);
253*7c478bd9Sstevel@tonic-gate 				}
254*7c478bd9Sstevel@tonic-gate /*
255*7c478bd9Sstevel@tonic-gate  *				if ((ufsaclp->acl_perm & ~07) != 0) {
256*7c478bd9Sstevel@tonic-gate  *					return (1);
257*7c478bd9Sstevel@tonic-gate  *				}
258*7c478bd9Sstevel@tonic-gate  */
259*7c478bd9Sstevel@tonic-gate 				numacls--;
260*7c478bd9Sstevel@tonic-gate 			}
261*7c478bd9Sstevel@tonic-gate 			break;
262*7c478bd9Sstevel@tonic-gate 		default:
263*7c478bd9Sstevel@tonic-gate 			break;
264*7c478bd9Sstevel@tonic-gate 		}
265*7c478bd9Sstevel@tonic-gate 	}
266*7c478bd9Sstevel@tonic-gate 	if ((caddr_t)fsdp != (buf + len)) {
267*7c478bd9Sstevel@tonic-gate 		return (1);
268*7c478bd9Sstevel@tonic-gate 	}
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 	/* If we didn't find any acls, ignore the unknown attribute */
271*7c478bd9Sstevel@tonic-gate 	if (ufsaclp == NULL)
272*7c478bd9Sstevel@tonic-gate 		return (0);
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate 	/* Check relationships amoung acls */
275*7c478bd9Sstevel@tonic-gate 	if (nuser_objs != 1 || ngroup_objs != 1 ||
276*7c478bd9Sstevel@tonic-gate 	    nother_objs != 1 || nclass_objs > 1) {
277*7c478bd9Sstevel@tonic-gate 		return (1);
278*7c478bd9Sstevel@tonic-gate 	}
279*7c478bd9Sstevel@tonic-gate 	if (ngroups && !nclass_objs) {
280*7c478bd9Sstevel@tonic-gate 		return (1);
281*7c478bd9Sstevel@tonic-gate 	}
282*7c478bd9Sstevel@tonic-gate 	if (ndef_other_objs > 1 || ndef_user_objs > 1 ||
283*7c478bd9Sstevel@tonic-gate 	    ndef_group_objs > 1 || ndef_class_objs > 1) {
284*7c478bd9Sstevel@tonic-gate 		return (1);
285*7c478bd9Sstevel@tonic-gate 	}
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 	/* Check relationships amoung default acls */
288*7c478bd9Sstevel@tonic-gate 	numdefs = ndef_other_objs + ndef_user_objs + ndef_group_objs;
289*7c478bd9Sstevel@tonic-gate 	if (numdefs != 0 && numdefs != 3) {
290*7c478bd9Sstevel@tonic-gate 		return (1);
291*7c478bd9Sstevel@tonic-gate 	}
292*7c478bd9Sstevel@tonic-gate 	if (ndef_groups && !ndef_class_objs) {
293*7c478bd9Sstevel@tonic-gate 		return (1);
294*7c478bd9Sstevel@tonic-gate 	}
295*7c478bd9Sstevel@tonic-gate 	if ((ndef_users || ndef_groups) &&
296*7c478bd9Sstevel@tonic-gate 	    ((numdefs != 3) && !ndef_class_objs)) {
297*7c478bd9Sstevel@tonic-gate 		return (1);
298*7c478bd9Sstevel@tonic-gate 	}
299*7c478bd9Sstevel@tonic-gate 	return (0);
300*7c478bd9Sstevel@tonic-gate }
301