2 * Copyright (c) 1997-1999 Erez Zadok
3 * Copyright (c) 1990 Jan-Simon Pendry
4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1990 The Regents of the University of California.
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgment:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * $Id: amq_subr.c,v 1.5 1999/08/24 21:31:06 ezk Exp $
42 * $FreeBSD: src/contrib/amd/amd/amq_subr.c,v 1.5 1999/09/15 05:45:13 obrien Exp $
43 * $DragonFly: src/contrib/amd/amd/amq_subr.c,v 1.2 2003/06/17 04:23:56 dillon Exp $
47 * Auxiliary routines for amq tool
52 #endif /* HAVE_CONFIG_H */
56 /* forward definitions */
57 bool_t
xdr_amq_mount_tree_node(XDR
*xdrs
, amq_mount_tree
*objp
);
58 bool_t
xdr_amq_mount_subtree(XDR
*xdrs
, amq_mount_tree
*objp
);
62 amqproc_null_1_svc(voidp argp
, struct svc_req
*rqstp
)
71 * Return a sub-tree of mounts
74 amqproc_mnttree_1_svc(voidp argp
, struct svc_req
*rqstp
)
78 mp
= find_ap(*(char **) argp
);
79 return (amq_mount_tree_p
*) &mp
;
84 * Unmount a single node
87 amqproc_umnt_1_svc(voidp argp
, struct svc_req
*rqstp
)
90 am_node
*mp
= find_ap(*(char **) argp
);
93 forcibly_timeout_mp(mp
);
100 * Return global statistics
103 amqproc_stats_1_svc(voidp argp
, struct svc_req
*rqstp
)
105 return (amq_mount_stats
*) &amd_stats
;
110 * Return the entire tree of mount nodes
112 amq_mount_tree_list
*
113 amqproc_export_1_svc(voidp argp
, struct svc_req
*rqstp
)
115 static amq_mount_tree_list aml
;
117 aml
.amq_mount_tree_list_val
= (amq_mount_tree_p
*) &exported_ap
[0];
118 aml
.amq_mount_tree_list_len
= 1; /* XXX */
125 amqproc_setopt_1_svc(voidp argp
, struct svc_req
*rqstp
)
128 amq_setopt
*opt
= (amq_setopt
*) argp
;
132 switch (opt
->as_opt
) {
136 if (debug_option(opt
->as_str
))
142 if (gopt
.logfile
&& opt
->as_str
143 && STREQ(gopt
.logfile
, opt
->as_str
)) {
144 if (switch_to_logfile(opt
->as_str
, orig_umask
))
152 if (switch_option(opt
->as_str
))
156 case AMOPT_FLUSHMAPC
:
157 if (amd_state
== Run
) {
158 plog(XLOG_INFO
, "amq says flush cache");
160 flush_nfs_fhandle_cache((fserver
*) 0);
161 flush_srvr_nfs_cache();
170 amq_mount_info_list
*
171 amqproc_getmntfs_1_svc(voidp argp
, struct svc_req
*rqstp
)
173 return (amq_mount_info_list
*) &mfhead
; /* XXX */
176 #ifdef ENABLE_AMQ_MOUNT
178 * This is code that is vulnerable to IP spoofing attacks. Unless you
179 * absolutely need it, I suggest you do not enable it
180 * (using configure --enable-amq-mount)
183 ok_security(struct svc_req
*rqstp
)
185 struct sockaddr_in
*sin
= (struct sockaddr_in
*) NULL
;
187 if ((sin
= amu_svc_getcaller(rqstp
->rq_xprt
)) == NULL
) {
188 plog(XLOG_ERROR
, "amu_svc_getcaller returned NULL");
189 return(0); /* assume security is therefore not OK */
192 if (ntohs(sin
->sin_port
) >= IPPORT_RESERVED
||
193 !(sin
->sin_addr
.s_addr
== htonl(0x7f000001) ||
194 sin
->sin_addr
.s_addr
== myipaddr
.s_addr
)) {
196 plog(XLOG_INFO
, "AMQ request from %s.%d DENIED",
197 inet_dquad(dq
, sin
->sin_addr
.s_addr
),
198 ntohs(sin
->sin_port
));
207 amqproc_mount_1_svc(voidp argp
, struct svc_req
*rqstp
)
209 static int rc
= EINVAL
;
213 struct sockaddr_in
*sin
;
215 if ((sin
= amu_svc_getcaller(rqstp
->rq_xprt
)) == NULL
) {
216 plog(XLOG_ERROR
, "amu_svc_getcaller returned NULL");
220 strncpy(s
, *(amq_string
*) argp
, AMQ_STRLEN
-1);
221 s
[AMQ_STRLEN
-1] = '\0'; /* null terminate, to be sure */
223 "amq requested mount of %s from %s.%d",
224 s
, inet_dquad(dq
, sin
->sin_addr
.s_addr
),
225 ntohs(sin
->sin_port
));
228 * Minimalist security check.
230 if (!ok_security(rqstp
)) {
237 for (cp
= (char *) s
; *cp
&& (!isascii(*cp
) || !isspace(*cp
)); cp
++) ;
240 plog(XLOG_INFO
, "amqproc_mount: Invalid arguments");
247 * Find start of value
249 while (*cp
&& isascii(*cp
) && isspace(*cp
))
252 root_newmap(s
, cp
, (char *) 0, NULL
);
253 rc
= mount_auto_node(s
, (voidp
) root_node
);
258 #endif /* ENABLE_AMQ_MOUNT */
262 amqproc_getvers_1_svc(voidp argp
, struct svc_req
*rqstp
)
264 static amq_string res
;
266 res
= get_version_string();
271 /* get PID of remote amd */
273 amqproc_getpid_1_svc(voidp argp
, struct svc_req
*rqstp
)
288 xdr_amq_setopt(XDR
*xdrs
, amq_setopt
*objp
)
290 if (!xdr_enum(xdrs
, (enum_t
*) & objp
->as_opt
)) {
293 if (!xdr_string(xdrs
, &objp
->as_str
, AMQ_STRLEN
)) {
301 * More XDR routines - Should be used for OUTPUT ONLY.
304 xdr_amq_mount_tree_node(XDR
*xdrs
, amq_mount_tree
*objp
)
306 am_node
*mp
= (am_node
*) objp
;
309 if (!xdr_amq_string(xdrs
, &mp
->am_mnt
->mf_info
)) {
312 if (!xdr_amq_string(xdrs
, &mp
->am_path
)) {
315 if (!xdr_amq_string(xdrs
, mp
->am_link
? &mp
->am_link
: &mp
->am_mnt
->mf_mount
)) {
318 if (!xdr_amq_string(xdrs
, &mp
->am_mnt
->mf_ops
->fs_type
)) {
321 mtime
= mp
->am_stats
.s_mtime
;
322 if (!xdr_long(xdrs
, &mtime
)) {
325 if (!xdr_u_short(xdrs
, &mp
->am_stats
.s_uid
)) {
328 if (!xdr_int(xdrs
, &mp
->am_stats
.s_getattr
)) {
331 if (!xdr_int(xdrs
, &mp
->am_stats
.s_lookup
)) {
334 if (!xdr_int(xdrs
, &mp
->am_stats
.s_readdir
)) {
337 if (!xdr_int(xdrs
, &mp
->am_stats
.s_readlink
)) {
340 if (!xdr_int(xdrs
, &mp
->am_stats
.s_statfs
)) {
348 xdr_amq_mount_subtree(XDR
*xdrs
, amq_mount_tree
*objp
)
350 am_node
*mp
= (am_node
*) objp
;
352 if (!xdr_amq_mount_tree_node(xdrs
, objp
)) {
355 if (!xdr_pointer(xdrs
, (char **) &mp
->am_osib
, sizeof(amq_mount_tree
), (XDRPROC_T_TYPE
) xdr_amq_mount_subtree
)) {
358 if (!xdr_pointer(xdrs
, (char **) &mp
->am_child
, sizeof(amq_mount_tree
), (XDRPROC_T_TYPE
) xdr_amq_mount_subtree
)) {
366 xdr_amq_mount_tree(XDR
*xdrs
, amq_mount_tree
*objp
)
368 am_node
*mp
= (am_node
*) objp
;
371 if (!xdr_amq_mount_tree_node(xdrs
, objp
)) {
374 if (!xdr_pointer(xdrs
, (char **) &mnil
, sizeof(amq_mount_tree
), (XDRPROC_T_TYPE
) xdr_amq_mount_subtree
)) {
377 if (!xdr_pointer(xdrs
, (char **) &mp
->am_child
, sizeof(amq_mount_tree
), (XDRPROC_T_TYPE
) xdr_amq_mount_subtree
)) {
385 xdr_amq_mount_tree_p(XDR
*xdrs
, amq_mount_tree_p
*objp
)
387 if (!xdr_pointer(xdrs
, (char **) objp
, sizeof(amq_mount_tree
), (XDRPROC_T_TYPE
) xdr_amq_mount_tree
)) {
395 xdr_amq_mount_stats(XDR
*xdrs
, amq_mount_stats
*objp
)
397 if (!xdr_int(xdrs
, &objp
->as_drops
)) {
400 if (!xdr_int(xdrs
, &objp
->as_stale
)) {
403 if (!xdr_int(xdrs
, &objp
->as_mok
)) {
406 if (!xdr_int(xdrs
, &objp
->as_merr
)) {
409 if (!xdr_int(xdrs
, &objp
->as_uerr
)) {
418 xdr_amq_mount_tree_list(XDR
*xdrs
, amq_mount_tree_list
*objp
)
421 (char **) &objp
->amq_mount_tree_list_val
,
422 (u_int
*) &objp
->amq_mount_tree_list_len
,
424 sizeof(amq_mount_tree_p
),
425 (XDRPROC_T_TYPE
) xdr_amq_mount_tree_p
)) {
434 * Compute length of list
437 xdr_amq_mount_info_qelem(XDR
*xdrs
, qelem
*qhead
)
442 for (mf
= AM_LAST(mntfs
, qhead
); mf
!= HEAD(mntfs
, qhead
); mf
= PREV(mntfs
, mf
)) {
443 if (!(mf
->mf_ops
->fs_flags
& FS_AMQINFO
))
447 xdr_u_int(xdrs
, &len
);
450 * Send individual data items
452 for (mf
= AM_LAST(mntfs
, qhead
); mf
!= HEAD(mntfs
, qhead
); mf
= PREV(mntfs
, mf
)) {
454 if (!(mf
->mf_ops
->fs_flags
& FS_AMQINFO
))
457 if (!xdr_amq_string(xdrs
, &mf
->mf_ops
->fs_type
)) {
460 if (!xdr_amq_string(xdrs
, &mf
->mf_mount
)) {
463 if (!xdr_amq_string(xdrs
, &mf
->mf_info
)) {
466 if (!xdr_amq_string(xdrs
, &mf
->mf_server
->fs_host
)) {
469 if (!xdr_int(xdrs
, &mf
->mf_error
)) {
472 if (!xdr_int(xdrs
, &mf
->mf_refc
)) {
475 if (mf
->mf_server
->fs_flags
& FSF_ERROR
)
478 switch (mf
->mf_server
->fs_flags
& (FSF_DOWN
| FSF_VALID
)) {
479 case FSF_DOWN
| FSF_VALID
:
489 if (!xdr_int(xdrs
, &up
)) {
498 xdr_pri_free(XDRPROC_T_TYPE xdr_args
, caddr_t args_ptr
)
503 return ((*xdr_args
) (&xdr
, (caddr_t
*) args_ptr
));