summaryrefslogtreecommitdiffstats
path: root/contrib/amd/hlfsd/stubs.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/amd/hlfsd/stubs.c')
-rw-r--r--contrib/amd/hlfsd/stubs.c530
1 files changed, 530 insertions, 0 deletions
diff --git a/contrib/amd/hlfsd/stubs.c b/contrib/amd/hlfsd/stubs.c
new file mode 100644
index 0000000..2ead112
--- /dev/null
+++ b/contrib/amd/hlfsd/stubs.c
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 1997-1998 Erez Zadok
+ * Copyright (c) 1989 Jan-Simon Pendry
+ * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry at Imperial College, London.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * %W% (Berkeley) %G%
+ *
+ * $Id: stubs.c,v 1.10 1993/09/13 15:11:00 ezk Exp $
+ *
+ * HLFSD was written at Columbia University Computer Science Department, by
+ * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
+ * It is being distributed under the same terms and conditions as amd does.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+#include <am_defs.h>
+#include <hlfsd.h>
+
+/*
+ * STATIC VARIABLES:
+ */
+static nfsfattr rootfattr = {NFDIR, 0040555, 2, 0, 0, 512, 512, 0,
+ 1, 0, ROOTID};
+static nfsfattr slinkfattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
+ (NFS_MAXPATHLEN + 1) / 512, 0, SLINKID};
+ /* user name file attributes */
+static nfsfattr un_fattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
+ (NFS_MAXPATHLEN + 1) / 512, 0, INVALIDID};
+static int getcreds(struct svc_req *, uid_t *, gid_t *);
+static int started;
+static am_nfs_fh slink;
+static am_nfs_fh un_fhandle;
+
+/*
+ * GLOBALS:
+ */
+am_nfs_fh root;
+am_nfs_fh *root_fhp = &root;
+
+
+/* initialize NFS file handles for hlfsd */
+void
+hlfsd_init_filehandles(void)
+{
+ u_int ui;
+
+ ui = ROOTID;
+ memcpy(root.fh_data, &ui, sizeof(ui));
+
+ ui = SLINKID;
+ memcpy(slink.fh_data, &ui, sizeof(ui));
+
+ ui = INVALIDID;
+ memcpy(un_fhandle.fh_data, &ui, sizeof(ui));
+}
+
+
+voidp
+nfsproc_null_2_svc(voidp argp, struct svc_req *rqstp)
+{
+ static char res;
+
+ return (voidp) &res;
+}
+
+
+/* compare if two filehandles are equal */
+static int
+eq_fh(const am_nfs_fh *fh1, const am_nfs_fh *fh2)
+{
+ return (!memcmp((char *) fh1, (char *) fh2, sizeof(am_nfs_fh)));
+}
+
+
+nfsattrstat *
+nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
+{
+ static nfsattrstat res;
+ uid_t uid = (uid_t) INVALIDID;
+ gid_t gid = (gid_t) INVALIDID;
+
+ if (!started) {
+ started++;
+ rootfattr.na_ctime = startup;
+ rootfattr.na_mtime = startup;
+ slinkfattr.na_ctime = startup;
+ slinkfattr.na_mtime = startup;
+ un_fattr.na_ctime = startup;
+ un_fattr.na_mtime = startup;
+ }
+
+ if (eq_fh(argp, &root)) {
+ res.ns_status = NFS_OK;
+ res.ns_u.ns_attr_u = rootfattr;
+ } else if (eq_fh(argp, &slink)) {
+
+#ifndef MNT2_NFS_OPT_SYMTTL
+ /*
+ * This code is needed to defeat Solaris 2.4's (and newer) symlink
+ * values cache. It forces the last-modifed time of the symlink to be
+ * current. It is not needed if the O/S has an nfs flag to turn off the
+ * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
+ */
+ if (++slinkfattr.na_mtime.nt_useconds == 0)
+ ++slinkfattr.na_mtime.nt_seconds;
+#endif /* not MNT2_NFS_OPT_SYMTTL */
+
+ res.ns_status = NFS_OK;
+ res.ns_u.ns_attr_u = slinkfattr;
+ } else {
+
+ if (getcreds(rqstp, &uid, &gid) < 0) {
+ res.ns_status = NFSERR_STALE;
+ return &res;
+ }
+ if (gid != hlfs_gid) {
+ res.ns_status = NFSERR_STALE;
+ } else {
+ memset((char *) &uid, 0, sizeof(int));
+ uid = *(u_int *) argp->fh_data;
+ if (plt_search(uid) != (uid2home_t *) NULL) {
+ res.ns_status = NFS_OK;
+ un_fattr.na_fileid = uid;
+ res.ns_u.ns_attr_u = un_fattr;
+#ifdef DEBUG
+ dlog("nfs_getattr: succesful search for uid=%d, gid=%d", uid, gid);
+#endif /* DEBUG */
+ } else { /* not found */
+ res.ns_status = NFSERR_STALE;
+ }
+ }
+ }
+ return &res;
+}
+
+
+nfsattrstat *
+nfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp)
+{
+ static nfsattrstat res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+voidp
+nfsproc_root_2_svc(voidp argp, struct svc_req *rqstp)
+{
+ static char res;
+
+ return (voidp) &res;
+}
+
+
+nfsdiropres *
+nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
+{
+ static nfsdiropres res;
+ int idx;
+ uid_t uid = (uid_t) INVALIDID;
+ gid_t gid = (gid_t) INVALIDID;
+
+ if (!started) {
+ started++;
+ rootfattr.na_ctime = startup;
+ rootfattr.na_mtime = startup;
+ slinkfattr.na_ctime = startup;
+ slinkfattr.na_mtime = startup;
+ un_fattr.na_ctime = startup;
+ un_fattr.na_mtime = startup;
+ }
+
+ if (eq_fh(&argp->da_fhandle, &slink)) {
+ res.dr_status = NFSERR_NOTDIR;
+ return &res;
+ }
+
+ if (eq_fh(&argp->da_fhandle, &root)) {
+ if (argp->da_name[0] == '.' &&
+ (argp->da_name[1] == '\0' ||
+ (argp->da_name[1] == '.' &&
+ argp->da_name[2] == '\0'))) {
+ res.dr_u.dr_drok_u.drok_fhandle = root;
+ res.dr_u.dr_drok_u.drok_attributes = rootfattr;
+ res.dr_status = NFS_OK;
+ return &res;
+ }
+
+ if (STREQ(argp->da_name, slinkname)) {
+ res.dr_u.dr_drok_u.drok_fhandle = slink;
+ res.dr_u.dr_drok_u.drok_attributes = slinkfattr;
+ res.dr_status = NFS_OK;
+ return &res;
+ }
+
+ if (getcreds(rqstp, &uid, &gid) < 0 || gid != hlfs_gid) {
+ res.dr_status = NFSERR_NOENT;
+ return &res;
+ }
+
+ /* if get's here, gid == hlfs_gid */
+ if ((idx = untab_index(argp->da_name)) < 0) {
+ res.dr_status = NFSERR_NOENT;
+ return &res;
+ } else { /* entry found and gid is permitted */
+ un_fattr.na_fileid = untab[idx].uid;
+ res.dr_u.dr_drok_u.drok_attributes = un_fattr;
+ memset((char *) &un_fhandle, 0, sizeof(am_nfs_fh));
+ *(u_int *) un_fhandle.fh_data = (u_int) untab[idx].uid;
+ strncpy((char *) &un_fhandle.fh_data[sizeof(int)],
+ untab[idx].username,
+ sizeof(am_nfs_fh) - sizeof(int));
+ res.dr_u.dr_drok_u.drok_fhandle = un_fhandle;
+ res.dr_status = NFS_OK;
+#ifdef DEBUG
+ dlog("nfs_lookup: succesful lookup for uid=%d, gid=%d: username=%s",
+ uid, gid, untab[idx].username);
+#endif /* DEBUG */
+ return &res;
+ }
+ } /* end of "if (eq_fh(argp->dir.data, root.data)) {" */
+
+ res.dr_status = NFSERR_STALE;
+ return &res;
+}
+
+static int
+getcreds(struct svc_req *rp, uid_t *u, gid_t *g)
+{
+ struct authunix_parms *aup = (struct authunix_parms *) NULL;
+#ifdef HAVE_RPC_AUTH_DES_H
+ struct authdes_cred *adp;
+#endif /* HAVE_RPC_AUTH_DES_H */
+
+ switch (rp->rq_cred.oa_flavor) {
+
+ case AUTH_UNIX:
+ aup = (struct authunix_parms *) rp->rq_clntcred;
+ *u = aup->aup_uid;
+ *g = aup->aup_gid;
+ break;
+
+#ifdef HAVE_RPC_AUTH_DES_H
+ case AUTH_DES:
+ adp = (struct authdes_cred *) rp->rq_clntcred;
+ *g = INVALIDID; /* some unknown group id */
+ if (sscanf(adp->adc_fullname.name, "unix.%lu@", u) == 1)
+ break;
+ /* fall through */
+#endif /* HAVE_RPC_AUTH_DES_H */
+
+ default:
+ *u = *g = INVALIDID; /* just in case */
+ svcerr_weakauth(nfsxprt);
+ return -1;
+ }
+
+ return 0; /* everything is ok */
+}
+
+
+nfsreadlinkres *
+nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
+{
+ static nfsreadlinkres res;
+ uid_t userid = (uid_t) INVALIDID;
+ gid_t groupid = hlfs_gid + 1; /* anything not hlfs_gid */
+ int retval = 0;
+ char *path_val = (char *) NULL;
+ char *username;
+ static uid_t last_uid = (uid_t) INVALIDID;
+
+ if (eq_fh(argp, &root)) {
+ res.rlr_status = NFSERR_ISDIR;
+ } else if (eq_fh(argp, &slink)) {
+ if (getcreds(rqstp, &userid, &groupid) < 0)
+ return (nfsreadlinkres *) NULL;
+
+ gettimeofday((struct timeval *) &slinkfattr.na_atime, (struct timezone *) 0);
+
+ res.rlr_status = NFS_OK;
+ if (groupid == hlfs_gid) {
+ res.rlr_u.rlr_data_u = DOTSTRING;
+ } else if (!(res.rlr_u.rlr_data_u = path_val = homedir(userid))) {
+ /*
+ * parent process (fork in homedir()) continues
+ * processing, by getting a NULL returned as a
+ * "special". Child returns result.
+ */
+ return (nfsreadlinkres *) NULL;
+ }
+
+ } else { /* check if asked for user mailbox */
+
+ if (getcreds(rqstp, &userid, &groupid) < 0) {
+ return (nfsreadlinkres *) NULL;
+ }
+
+ if (groupid == hlfs_gid) {
+ memset((char *) &userid, 0, sizeof(int));
+ userid = *(u_int *) argp->fh_data;
+ username = (char *) &argp->fh_data[sizeof(int)];
+ if (!(res.rlr_u.rlr_data_u = mailbox(userid, username)))
+ return (nfsreadlinkres *) NULL;
+ } else {
+ res.rlr_status = NFSERR_STALE;
+ }
+ }
+
+ /* print info, but try to avoid repetitions */
+ if (userid != last_uid) {
+ plog(XLOG_USER, "mailbox for uid=%d, gid=%d is %s",
+ userid, groupid, (char *) res.rlr_u.rlr_data_u);
+ last_uid = userid;
+ }
+
+ /* I don't think will pass this if -D nofork */
+ if (serverpid == getpid())
+ return &res;
+
+ if (!svc_sendreply(nfsxprt, (XDRPROC_T_TYPE) xdr_readlinkres, (SVC_IN_ARG_TYPE) &res))
+ svcerr_systemerr(nfsxprt);
+
+ /*
+ * Child exists here. We need to determine which
+ * exist status to return. The exit status
+ * is gathered using wait() and determines
+ * if we returned $HOME/.hlfsspool or $ALTDIR. The parent
+ * needs this info so it can update the lookup table.
+ */
+ if (path_val && alt_spooldir && STREQ(path_val, alt_spooldir))
+ retval = 1; /* could not get real home dir (or uid 0 user) */
+ else
+ retval = 0;
+
+#ifdef DEBUG
+ /*
+ * If asked for -D nofork, then must return the value,
+ * NOT exit, or else the main hlfsd server exits.
+ * Bug where is that status information being collected?
+ */
+ amuDebugNo(D_FORK)
+ return &res;
+#endif /* DEBUG */
+
+ exit(retval);
+}
+
+
+nfsreadres *
+nfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp)
+{
+ static nfsreadres res = {NFSERR_ACCES};
+
+ return &res;
+}
+
+
+voidp
+nfsproc_writecache_2_svc(voidp argp, struct svc_req *rqstp)
+{
+ static char res;
+
+ return (voidp) &res;
+}
+
+
+nfsattrstat *
+nfsproc_write_2_svc(nfswriteargs *argp, struct svc_req *rqstp)
+{
+ static nfsattrstat res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsdiropres *
+nfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
+{
+ static nfsdiropres res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsstat *
+nfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
+{
+ static nfsstat res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsstat *
+nfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp)
+{
+ static nfsstat res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsstat *
+nfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp)
+{
+ static nfsstat res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsstat *
+nfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp)
+{
+ static nfsstat res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsdiropres *
+nfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
+{
+ static nfsdiropres res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsstat *
+nfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
+{
+ static nfsstat res = {NFSERR_ROFS};
+
+ return &res;
+}
+
+
+nfsreaddirres *
+nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
+{
+ static nfsreaddirres res;
+ static nfsentry slinkent = {SLINKID, 0, {SLINKCOOKIE}};
+ static nfsentry dotdotent = {ROOTID, "..", {DOTDOTCOOKIE}, &slinkent};
+ static nfsentry dotent = {ROOTID, ".", {DOTCOOKIE}, &dotdotent};
+
+ slinkent.ne_name = slinkname;
+
+ if (eq_fh(&argp->rda_fhandle, &slink)) {
+ res.rdr_status = NFSERR_NOTDIR;
+ } else if (eq_fh(&argp->rda_fhandle, &root)) {
+ gettimeofday((struct timeval *) &rootfattr.na_atime, (struct timezone *) 0);
+
+ res.rdr_status = NFS_OK;
+ switch (argp->rda_cookie[0]) {
+ case 0:
+ res.rdr_u.rdr_reply_u.dl_entries = &dotent;
+ break;
+ case DOTCOOKIE:
+ res.rdr_u.rdr_reply_u.dl_entries = &dotdotent;
+ break;
+ case DOTDOTCOOKIE:
+ res.rdr_u.rdr_reply_u.dl_entries = &slinkent;
+ break;
+ case SLINKCOOKIE:
+ res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) 0;
+ break;
+ }
+ res.rdr_u.rdr_reply_u.dl_eof = TRUE;
+ } else {
+ res.rdr_status = NFSERR_STALE;
+ }
+ return &res;
+}
+
+
+nfsstatfsres *
+nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
+{
+ static nfsstatfsres res = {NFS_OK};
+
+ res.sfr_u.sfr_reply_u.sfrok_tsize = 1024;
+ res.sfr_u.sfr_reply_u.sfrok_bsize = 1024;
+
+ /*
+ * Some "df" programs automatically assume that file systems
+ * with zero blocks are meta-filesystems served by automounters.
+ */
+ res.sfr_u.sfr_reply_u.sfrok_blocks = 0;
+ res.sfr_u.sfr_reply_u.sfrok_bfree = 0;
+ res.sfr_u.sfr_reply_u.sfrok_bavail = 0;
+
+ return &res;
+}
OpenPOWER on IntegriCloud