📄 adm.c
字号:
/* $Id: adm.C,v 1.6 2001/06/25 06:39:37 dm Exp $ *//* * * Copyright (C) 2001 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */#include "getfh3.h"#include "cryptfsadm.h"#include "nfsmounter.h"#include "cryptfs.h"qhash<str, ref<cryptfs> > &fstab = *New qhash<str, ref<cryptfs> >;ptr<asrv> rootsrv;class cfsadm : public virtual refcount { authunix_parms *aup; const ref<asrv> s; void mount (svccb *sbp); void gotfs (svccb *sbp, ptr<nfsinfo> info, str err); void mounted (svccb *sbp, ref<cryptfs>, ref<mountres> resp, clnt_stat err); void dispatch (svccb *sbp);protected: cfsadm (ref<axprt_unix> x, const authunix_parms *aup); PRIVDEST ~cfsadm ();public: static void alloc (ptr<axprt_unix> x, const authunix_parms *aup) { if (x) vNew refcounted<cfsadm> (x, aup); }};cfsadm::cfsadm (ref<axprt_unix> x, const authunix_parms *au) : s (asrv::alloc (x, cfsadm_prog_1, wrap (this, &cfsadm::dispatch))){ aup = static_cast<authunix_parms *> (xmalloc (sizeof (*aup))); *aup = *au; *reinterpret_cast<void **> (&aup->aup_gids) = xmalloc (aup->aup_len * sizeof (aup->aup_gids[0])); memcpy (aup->aup_gids, au->aup_gids, aup->aup_len * sizeof (aup->aup_gids[0])); aup->aup_machname = "localhost"; refcount_inc ();}cfsadm::~cfsadm (){ xfree (aup->aup_gids); xfree (aup);}voidcfsadm::mount (svccb *sbp){ cfsadm_mount_arg *arg = sbp->template getarg<cfsadm_mount_arg> (); str2wstr (arg->pwd); if (arg->path[0] != '/' || arg->name[0] == '.' || strchr (arg->name, '/')) sbp->replyref (EINVAL); else if (uid_mkdir (aup2aid (aup), arg->name)) findfs (aup, arg->path, wrap (mkref (this), &cfsadm::gotfs, sbp)); else sbp->replyref (EEXIST);}voidcfsadm::gotfs (svccb *sbp, ptr<nfsinfo> info, str err){ cfsadm_mount_arg *arg = sbp->template getarg<cfsadm_mount_arg> (); if (err) { uid_rmdir (aup2aid (aup), arg->name); warn << err << "\n"; sbp->replyref (EIO); return; } ref<nfsserv_udp> nfss (New refcounted<nfsserv_udp>); ref<cryptfs> fs (New refcounted<cryptfs> (aup2aid (aup), nfss, info->c, arg->pwd, info->fd)); info->fd = -1; mountarg ma; ma.hostname = arg->path << "*"; ma.path = mountpoint (aup, arg->name); ma.flags = NMOPT_NFS3; ma.handle.set (const_cast<char *> (info->fh.data.base ()), info->fh.data.size ()); ref<mountres> mrp (New refcounted<mountres>); nmx->sendfd (nfss->getfd (), false); nmc->call (NFSMOUNTER_MOUNT, &ma, mrp, wrap (mkref(this), &cfsadm::mounted, sbp, fs, mrp));}voidcfsadm::mounted (svccb *sbp, ref<cryptfs> fs, ref<mountres> resp, clnt_stat err){ cfsadm_mount_arg *arg = sbp->template getarg<cfsadm_mount_arg> (); if (err) fatal << "nfsmounter: " << err << "\n"; if (resp->status) { uid_rmdir (aup2aid (aup), arg->name); warn << arg->name << ": " << strerror (resp->status) << "\n"; /* XXX - should somehow delete allocated cryptfs struct */ } else fstab.insert (mountpoint (aup, arg->name), fs); sbp->replyref (resp->status);}voidcfsadm::dispatch (svccb *sbp){ if (!sbp) { refcount_dec (); return; } switch (sbp->proc ()) { case CFSADMPROC_NULL: sbp->reply (NULL); break; case CFSADMPROC_MOUNT: mount (sbp); break; default: sbp->reject (PROC_UNAVAIL); break; }}static void unmount_send (sfs_aid aid, str name, bool logit);static voidunmount_cb (sfs_aid aid, str name, ref<int> res, clnt_stat err){ if (err) fatal << "nfsmounter: " << err << "\n"; if (*res) delaycb (5, wrap (unmount_send, aid, name, false)); else uid_rmdir (aid, name);}static voidunmount_send (sfs_aid aid, str name, bool logit){ umountarg arg; arg.path = mountpoint (aid, name); if (logit) arg.flags = NUOPT_FORCE|NUOPT_STALE; else arg.flags = NUOPT_FORCE|NUOPT_STALE|NUOPT_NLOG; ref<int> res = New refcounted<int> (EBUSY); nmc->call (NFSMOUNTER_UMOUNT, &arg, res, wrap (unmount_cb, aid, name, res));}booldetach (sfs_aid aid, str name){ str fsname = mountpoint (aid, name); cryptfs *cfsp = fstab[fsname]; if (!cfsp) return false; cfsp->kill (); fstab.remove (fsname); rootdir->aidunlink (aid, name); unmount_send (aid, name, true); return true;}static voidadm_mounted (ref<mountres> resp, clnt_stat err){ if (err) fatal << "nfsmounter: " << err << "\n"; if (resp->status) fatal << mntpath << ": " << strerror (resp->status) << "\n"; sfs_suidserv ("cryptfs", wrap (&cfsadm::alloc));}voidadm_init (void){ int nfsfd = inetsocket (SOCK_DGRAM, 0, INADDR_LOOPBACK); rootsrv = asrv::alloc (axprt_dgram::alloc (nfsfd), nfs_program_3, wrap (&afsnode::dispatch3)); nfs_fh3 fh; rootdir->mkfh3 (&fh); mountarg arg; arg.hostname = strbuf ("(%s)", progname.cstr ()); arg.path = mntpath; arg.flags = NMOPT_NFS3|NMOPT_NOAC; arg.handle.set (const_cast<char *> (fh.data.base ()), fh.data.size ()); ref<mountres> mrp (New refcounted<mountres>); nmx->sendfd (nfsfd, false); nmc->call (NFSMOUNTER_MOUNT, &arg, mrp, wrap (adm_mounted, mrp));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -