export.h revision 2140:043bd360aabc
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 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27/*	  All Rights Reserved  	*/
28
29#ifndef	_NFS_EXPORT_H
30#define	_NFS_EXPORT_H
31
32#pragma ident	"%Z%%M%	%I%	%E% SMI"
33
34#include <nfs/nfs_sec.h>
35#include <nfs/auth.h>
36#include <sys/vnode.h>
37#include <nfs/nfs4.h>
38
39#ifdef	__cplusplus
40extern "C" {
41#endif
42
43/*
44 * nfs pseudo flavor number is owned by IANA. Need to make sure the
45 * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
46 * new IANA defined pseudo flavor numbers. The chance for the overlap
47 * is very small since the growth of new flavor numbers is expected
48 * to be limited.
49 */
50#define	NFS_FLAVOR_NOMAP	999999	/* no nfs flavor mapping */
51
52/*
53 * As duplicate flavors can be passed into exportfs in the arguments, we
54 * allocate a cleaned up array with non duplicate flavors on the stack.
55 * So we need to know how much to allocate.
56 */
57#define	MAX_FLAVORS		6	/* none, sys, dh, krb5, krb5i krb5p */
58
59/*
60 * Note: exported_lock is currently used to ensure the integrity of
61 * the secinfo fields.
62 */
63struct secinfo {
64	seconfig_t	s_secinfo;	/* /etc/nfssec.conf entry */
65	unsigned int	s_flags;	/* flags (see below) */
66	int32_t		s_refcnt;	/* reference count for tracking */
67					/* how many children (self included) */
68					/* use this flavor. */
69	int 		s_window;	/* window */
70	int		s_rootcnt;	/* count of root names */
71	caddr_t		*s_rootnames;	/* array of root names */
72					/* they are strings for AUTH_DES and */
73					/* rpc_gss_principal_t for RPCSEC_GSS */
74};
75
76#ifdef _SYSCALL32
77struct secinfo32 {
78	seconfig32_t	s_secinfo;	/* /etc/nfssec.conf entry */
79	uint32_t	s_flags;	/* flags (see below) */
80	int32_t		s_refcnt;	/* reference count for tracking */
81					/* how many children (self included) */
82					/* use this flavor. */
83	int32_t 	s_window;	/* window */
84	int32_t		s_rootcnt;	/* count of root names */
85	caddr32_t	s_rootnames;	/* array of root names */
86					/* they are strings for AUTH_DES and */
87					/* rpc_gss_principal_t for RPCSEC_GSS */
88};
89#endif /* _SYSCALL32 */
90
91/*
92 * security negotiation related
93 */
94
95#define	SEC_QUERY	0x01	/* query sec modes */
96
97struct sec_ol {
98	int		sec_flags;	/* security nego flags */
99	uint_t		sec_index;	/* index into sec flavor array */
100};
101
102/*
103 * Per-mode flags (secinfo.s_flags)
104 */
105#define	M_RO		0x01	/* exported ro to all */
106#define	M_ROL		0x02	/* exported ro to all listed */
107#define	M_RW		0x04	/* exported rw to all */
108#define	M_RWL		0x08	/* exported ro to all listed */
109#define	M_ROOT		0x10	/* root list is defined */
110#define	M_4SEC_EXPORTED	0x20	/* this is an explicitly shared flavor */
111
112/* invalid secinfo reference count */
113#define	SEC_REF_INVALID(p) ((p)->s_refcnt < 1)
114
115/* last secinfo reference */
116#define	SEC_REF_LAST(p) ((p)->s_refcnt == 1)
117
118/* sec flavor explicitly shared for the exported node */
119#define	SEC_REF_EXPORTED(p) ((p)->s_flags & M_4SEC_EXPORTED)
120
121/* the only reference count left is for referring itself */
122#define	SEC_REF_SELF(p) (SEC_REF_LAST(p) && SEC_REF_EXPORTED(p))
123
124/*
125 * The export information passed to exportfs() (Version 2)
126 */
127#define	EX_CURRENT_VERSION 2	/* current version of exportdata struct */
128
129struct exportdata {
130	int		ex_version;	/* structure version */
131	char		*ex_path;	/* exported path */
132	size_t		ex_pathlen;	/* path length */
133	int		ex_flags;	/* flags */
134	unsigned int	ex_anon;	/* uid for unauthenticated requests */
135	int		ex_seccnt;	/* count of security modes */
136	struct secinfo	*ex_secinfo;	/* security mode info */
137	char		*ex_index;	/* index file for public filesystem */
138	char		*ex_log_buffer;	/* path to logging buffer file */
139	size_t		ex_log_bufferlen;	/* buffer file path len */
140	char		*ex_tag;	/* tag used to identify log config */
141	size_t		ex_taglen;	/* tag length */
142};
143
144#ifdef _SYSCALL32
145struct exportdata32 {
146	int32_t		ex_version;	/* structure version */
147	caddr32_t	ex_path;	/* exported path */
148	int32_t		ex_pathlen;	/* path length */
149	int32_t		ex_flags;	/* flags */
150	uint32_t	ex_anon;	/* uid for unauthenticated requests */
151	int32_t		ex_seccnt;	/* count of security modes */
152	caddr32_t	ex_secinfo;	/* security mode info */
153	caddr32_t	ex_index;	/* index file for public filesystem */
154	caddr32_t	ex_log_buffer;	/* path to logging buffer file */
155	int32_t		ex_log_bufferlen;	/* buffer file path len */
156	caddr32_t	ex_tag;		/* tag used to identify log config */
157	int32_t		ex_taglen;	/* tag length */
158};
159#endif /* _SYSCALL32 */
160
161/*
162 * exported vfs flags.
163 */
164
165#define	EX_NOSUID	0x01	/* exported with unsetable set[ug]ids */
166#define	EX_ACLOK	0x02	/* exported with maximal access if acl exists */
167#define	EX_PUBLIC	0x04	/* exported with public filehandle */
168#define	EX_NOSUB	0x08	/* no nfs_getfh or MCL below export point */
169#define	EX_INDEX	0x10	/* exported with index file specified */
170#define	EX_LOG		0x20	/* logging enabled */
171#define	EX_LOG_ALLOPS	0x40	/* logging of all RPC operations enabled */
172				/* by default only operations which affect */
173				/* transaction logging are enabled */
174#define	EX_PSEUDO	0x80	/* pseudo filesystem export */
175#ifdef VOLATILE_FH_TEST
176#define	EX_VOLFH	0x100	/* XXX nfsv4 fh may expire anytime */
177#define	EX_VOLRNM	0x200	/* XXX nfsv4 fh expire at rename */
178#define	EX_VOLMIG	0x400	/* XXX nfsv4 fh expire at migration */
179#define	EX_NOEXPOPEN	0x800	/* XXX nfsv4 fh no expire with open */
180#endif /* VOLATILE_FH_TEST */
181
182#ifdef	_KERNEL
183
184#define	RPC_IDEMPOTENT	0x1	/* idempotent or not */
185/*
186 * Be very careful about which NFS procedures get the RPC_ALLOWANON bit.
187 * Right now, it this bit is on, we ignore the results of per NFS request
188 * access control.
189 */
190#define	RPC_ALLOWANON	0x2	/* allow anonymous access */
191#define	RPC_MAPRESP	0x4	/* use mapped response buffer */
192#define	RPC_AVOIDWORK	0x8	/* do work avoidance for dups */
193#define	RPC_PUBLICFH_OK	0x10	/* allow use of public filehandle */
194
195/*
196 * RPC_ALL is an or of all above bits to be used with "don't care"
197 * nfsv4 ops. The flags of an nfsv4 request is the bit-AND of the
198 * per-op flags.
199 */
200#define	RPC_ALL	(RPC_IDEMPOTENT|RPC_ALLOWANON|RPC_AVOIDWORK|RPC_PUBLICFH_OK)
201
202
203#ifdef VOLATILE_FH_TEST
204struct ex_vol_rename {
205	nfs_fh4_fmt_t vrn_fh_fmt;
206	struct ex_vol_rename *vrn_next;
207};
208#endif /* VOLATILE_FH_TEST */
209
210/*
211 * An authorization cache entry
212 */
213struct auth_cache {
214	struct netbuf		auth_addr;
215	int			auth_flavor;
216	int			auth_access;
217	time_t			auth_time;
218	struct auth_cache	*auth_next;
219};
220
221#define	AUTH_TABLESIZE	32
222
223/*
224 * Structure containing log file meta-data.
225 */
226struct log_file {
227	unsigned int	lf_flags;	/* flags (see below) */
228	int		lf_writers;	/* outstanding writers */
229	int		lf_refcnt;	/* references to this struct */
230	caddr_t		lf_path;	/* buffer file location */
231	vnode_t		*lf_vp;		/* vnode for the buffer file */
232	kmutex_t	lf_lock;
233	kcondvar_t	lf_cv_waiters;
234};
235
236/*
237 * log_file and log_buffer flags.
238 */
239#define	L_WAITING	0x01		/* flush of in-core data to stable */
240					/* storage in progress */
241#define	L_PRINTED	0x02		/* error message printed to console */
242#define	L_ERROR		0x04		/* error condition detected */
243
244/*
245 * The logging buffer information.
246 * This structure may be shared by multiple exportinfo structures,
247 * if they share the same buffer file.
248 * This structure contains the basic information about the buffer, such
249 * as it's location in the filesystem.
250 *
251 * 'lb_lock' protects all the fields in this structure except for 'lb_path',
252 * and 'lb_next'.
253 * 'lb_path' is a write-once/read-many field which needs no locking, it is
254 * set before the structure is linked to any exportinfo structure.
255 * 'lb_next' is protected by the log_buffer_list_lock.
256 */
257struct log_buffer {
258	unsigned int	lb_flags;	/* L_ONLIST set? */
259	int		lb_refcnt;	/* references to this struct */
260	unsigned int	lb_rec_id;	/* used to generate unique id */
261	caddr_t		lb_path;	/* buffer file pathname */
262	struct log_file	*lb_logfile;	/* points to log_file structure */
263	kmutex_t	lb_lock;
264	struct log_buffer	*lb_next;
265	kcondvar_t	lb_cv_waiters;
266	caddr_t		lb_records;	/* linked list of records to write */
267	int		lb_num_recs;	/* # of records to write */
268	ssize_t		lb_size_queued; /* number of bytes queued for write */
269};
270
271#define	LOG_BUFFER_HOLD(lbp)	{ \
272	mutex_enter(&(lbp)->lb_lock); \
273	(lbp)->lb_refcnt++; \
274	mutex_exit(&(lbp)->lb_lock); \
275}
276
277#define	LOG_BUFFER_RELE(lbp)	{ \
278	log_buffer_rele(lbp); \
279}
280
281#define	EXPTABLESIZE	16
282
283/*
284 * A node associated with an export entry on the
285 * list of exported filesystems.
286 *
287 * exi_count+exi_lock protects an individual exportinfo from being freed
288 * when in use.
289 * You must have the writer lock on exported_lock to add/delete an exportinfo
290 * structure to/from the list.
291 *
292 * exi_volatile_dev maps to VSW_VOLATILEDEV.  It means that the
293 * underlying fs devno can change on each mount.  When set, the server
294 * should not use va_fsid for a GETATTR(FATTR4_FSID) reply.  It must
295 * use exi_fsid because it is guaranteed to be persistent.  This isn't
296 * in any way related to NFS4 volatile filehandles.
297 */
298struct exportinfo {
299	struct exportdata	exi_export;
300	fsid_t			exi_fsid;
301	struct fid		exi_fid;
302	struct exportinfo	*exi_hash;
303	fhandle_t		exi_fh;
304	krwlock_t		exi_cache_lock;
305	kmutex_t		exi_lock;
306	uint_t			exi_count;
307	vnode_t			*exi_vp;
308	vnode_t			*exi_dvp;
309	struct auth_cache	*exi_cache[AUTH_TABLESIZE];
310	struct log_buffer	*exi_logbuffer;
311	struct exp_visible	*exi_visible;
312	unsigned		exi_volatile_dev:1;
313#ifdef VOLATILE_FH_TEST
314	uint32_t		exi_volatile_id;
315	struct ex_vol_rename	*exi_vol_rename;
316	kmutex_t		exi_vol_rename_lock;
317#endif /* VOLATILE_FH_TEST */
318};
319
320/*
321 * exp_visible is a visible list per filesystem. It is for filesystems
322 * that may need a limited view of its contents. A pseudo export and
323 * a real export at the mount point (VROOT) which has a subtree shared
324 * has a visible list.
325 *
326 * The exi_visible field is NULL for normal, non=pseudo filesystems
327 * which do not have any subtree exported. If the field is non-null,
328 * it points to a list of visible entries, identified by vis_fid and/or
329 * vis_ino. The presence of a "visible" list means that if this export
330 * can only have a limited view, it can only view the entries in the
331 * exp_visible list. The directories in the fid list comprise paths that
332 * lead to exported directories.
333 *
334 * The vis_count field records the number of paths in this filesystem
335 * that use this directory. The vis_exported field is non-zero if the
336 * entry is an exported directory (leaf node).
337 */
338
339struct exp_visible {
340	vnode_t			*vis_vp;
341	fid_t			vis_fid;
342	u_longlong_t		vis_ino;
343	int			vis_count;
344	int			vis_exported;
345	struct exp_visible	*vis_next;
346};
347
348#define	PSEUDO(exi)	((exi)->exi_export.ex_flags & EX_PSEUDO)
349
350#define	EQFSID(fsidp1, fsidp2)	\
351	(((fsidp1)->val[0] == (fsidp2)->val[0]) && \
352	    ((fsidp1)->val[1] == (fsidp2)->val[1]))
353
354#define	EQFID(fidp1, fidp2)	\
355	((fidp1)->fid_len == (fidp2)->fid_len && \
356	    bcmp((char *)(fidp1)->fid_data, (char *)(fidp2)->fid_data, \
357	    (uint_t)(fidp1)->fid_len) == 0)
358
359#define	exportmatch(exi, fsid, fid)	\
360	(EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
361
362/*
363 * Returns true iff exported filesystem is read-only to the given host.
364 *
365 * Note:  this macro should be as fast as possible since it's called
366 * on each NFS modification request.
367 */
368#define	rdonly(exi, req)  (nfsauth_access(exi, req) & NFSAUTH_RO)
369#define	rdonly4(exi, vp, req)  \
370	(vn_is_readonly(vp) || \
371	    (nfsauth4_access(exi, vp, req) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
372
373extern int	nfsauth4_access(struct exportinfo *, vnode_t *,
374				struct svc_req *);
375extern int	nfsauth4_secinfo_access(struct exportinfo *,
376				struct svc_req *, int, int);
377extern int	nfs_fhhash(fsid_t *, fid_t *);
378extern int	nfs_fhbcmp(char *, char *, int);
379extern int	nfs_exportinit(void);
380extern void	nfs_exportfini(void);
381extern int	chk_clnt_sec(struct exportinfo *, struct svc_req *req);
382extern int	makefh(fhandle_t *, struct vnode *, struct exportinfo *);
383extern int	makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
384extern int	makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
385extern int	makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
386extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
387extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
388extern vnode_t *lm_fhtovp(fhandle_t *fh);
389extern vnode_t *lm_nfs3_fhtovp(nfs_fh3 *fh);
390extern struct	exportinfo *checkexport(fsid_t *, struct fid *);
391extern struct	exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *vp);
392extern void	exi_rele(struct exportinfo *);
393extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
394    int *, bool_t);
395extern int	nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
396			struct exportinfo **);
397extern void	export_link(struct exportinfo *);
398extern int	export_unlink(fsid_t *, fid_t *, vnode_t *,
399			struct exportinfo **);
400extern vnode_t *untraverse(vnode_t *);
401
402/*
403 * Functions that handle the NFSv4 server namespace
404 */
405extern int	treeclimb_export(struct exportinfo *);
406extern int	treeclimb_unexport(struct exportinfo *);
407extern int	nfs_visible(struct exportinfo *, vnode_t *, int *);
408extern int	nfs_visible_inode(struct exportinfo *, ino64_t, int *);
409extern int	has_visible(struct exportinfo *, vnode_t *);
410extern void	free_visible(struct exp_visible *);
411extern int	nfs_exported(struct exportinfo *, vnode_t *);
412extern int	pseudo_exportfs(vnode_t *, struct exp_visible *,
413					struct exportdata *);
414extern int	vop_fid_pseudo(vnode_t *, fid_t *fidp);
415extern int	nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
416/*
417 * Functions that handle the NFSv4 server namespace security flavors
418 * information.
419 */
420extern void	srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
421
422/*
423 * "public" and default (root) location for public filehandle
424 */
425extern struct exportinfo *exi_public, *exi_root;
426extern fhandle_t nullfh2;	/* for comparing V2 filehandles */
427extern krwlock_t exported_lock;
428extern struct exportinfo *exptable[];
429
430/*
431 * Two macros for identifying public filehandles.
432 * A v2 public filehandle is 32 zero bytes.
433 * A v3 public filehandle is zero length.
434 */
435#define	PUBLIC_FH2(fh) \
436	((fh)->fh_fsid.val[1] == 0 && \
437	bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
438
439#define	PUBLIC_FH3(fh) \
440	((fh)->fh3_length == 0)
441
442extern int	makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
443extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
444
445#endif /* _KERNEL */
446
447#ifdef	__cplusplus
448}
449#endif
450
451#endif	/* _NFS_EXPORT_H */
452