summaryrefslogtreecommitdiffstats
path: root/sys/netncp/ncp_mod.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netncp/ncp_mod.c')
-rw-r--r--sys/netncp/ncp_mod.c529
1 files changed, 0 insertions, 529 deletions
diff --git a/sys/netncp/ncp_mod.c b/sys/netncp/ncp_mod.c
deleted file mode 100644
index 955fa31..0000000
--- a/sys/netncp/ncp_mod.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*-
- * Copyright (c) 2003 Tim J. Robbins.
- * Copyright (c) 1999, 2000, 2001 Boris Popov
- * All rights reserved.
- *
- * 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 Boris Popov.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/malloc.h>
-#include <sys/uio.h>
-#include <sys/ioccom.h>
-
-#include <netncp/ncp.h>
-#include <netncp/ncp_conn.h>
-#include <netncp/ncp_subr.h>
-#include <netncp/ncp_ncp.h>
-#include <netncp/ncp_user.h>
-#include <netncp/ncp_rq.h>
-#include <netncp/ncp_nls.h>
-#include <netncp/ncpio.h>
-
-int ncp_version = NCP_VERSION;
-
-SYSCTL_NODE(_net, OID_AUTO, ncp, CTLFLAG_RW, NULL, "NetWare requester");
-SYSCTL_INT(_net_ncp, OID_AUTO, version, CTLFLAG_RD, &ncp_version, 0, "");
-
-MODULE_VERSION(ncp, 1);
-MODULE_DEPEND(ncp, libmchain, 1, 1, 1);
-
-static struct cdev *ncp_dev;
-
-static d_ioctl_t ncp_ioctl;
-
-static struct cdevsw ncp_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_ioctl = ncp_ioctl,
- .d_name = "ncp",
-};
-
-static int ncp_conn_frag_rq(struct ncp_conn *, struct thread *,
- struct ncp_conn_frag *);
-static int ncp_conn_handler(struct thread *, struct ncpioc_request *,
- struct ncp_conn *, struct ncp_handle *);
-static int sncp_conn_scan(struct thread *, struct ncpioc_connscan *);
-static int sncp_connect(struct thread *, struct ncpioc_connect *);
-static int sncp_request(struct thread *, struct ncpioc_request *);
-
-static int
-ncp_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
-{
-
- switch (cmd) {
- case NCPIOC_CONNECT:
- return (sncp_connect(td, (struct ncpioc_connect *)data));
- case NCPIOC_CONNSCAN:
- return (sncp_conn_scan(td, (struct ncpioc_connscan *)data));
- case NCPIOC_REQUEST:
- return (sncp_request(td, (struct ncpioc_request *)data));
- }
- return (EINVAL);
-}
-
-/*
- * Attach to NCP server
- */
-
-static int
-sncp_connect(struct thread *td, struct ncpioc_connect *args)
-{
- int connHandle = 0, error;
- struct ncp_conn *conn;
- struct ncp_handle *handle;
- struct ncp_conn_args li;
-
- checkbad(copyin(args->ioc_li,&li,sizeof(li)));
- /* XXX Should be useracc() */
- checkbad(copyout(&connHandle,args->ioc_connhandle,
- sizeof(connHandle)));
- li.password = li.user = NULL;
- error = ncp_conn_getattached(&li, td, td->td_ucred, NCPM_WRITE | NCPM_EXECUTE, &conn);
- if (error) {
- error = ncp_conn_alloc(&li, td, td->td_ucred, &conn);
- if (error)
- goto bad;
- error = ncp_conn_reconnect(conn);
- if (error)
- ncp_conn_free(conn);
- }
- if (!error) {
- error = ncp_conn_gethandle(conn, td, &handle);
- copyout(&handle->nh_id, args->ioc_connhandle,
- sizeof(args->ioc_connhandle));
- ncp_conn_unlock(conn,td);
- }
-bad:
- return error;
-}
-
-static int
-sncp_request(struct thread *td, struct ncpioc_request *args)
-{
- struct ncp_rq *rqp;
- struct ncp_conn *conn;
- struct ncp_handle *handle;
- int error = 0, rqsize;
-
- error = ncp_conn_findhandle(args->ioc_connhandle, td, &handle);
- if (error)
- return error;
- conn = handle->nh_conn;
- if (args->ioc_fn == NCP_CONN)
- return ncp_conn_handler(td, args, conn, handle);
- error = copyin(&args->ioc_ncpbuf->rqsize, &rqsize, sizeof(int));
- if (error)
- return(error);
- error = ncp_rq_alloc(args->ioc_fn, conn, td, td->td_ucred, &rqp);
- if (error)
- return error;
- if (rqsize) {
- error = mb_put_mem(&rqp->rq, (caddr_t)args->ioc_ncpbuf->packet,
- rqsize, MB_MUSER);
- if (error)
- goto bad;
- }
- rqp->nr_flags |= NCPR_DONTFREEONERR;
- error = ncp_request(rqp);
- if (error == 0 && rqp->nr_rpsize)
- error = md_get_mem(&rqp->rp, (caddr_t)args->ioc_ncpbuf->packet,
- rqp->nr_rpsize, MB_MUSER);
- copyout(&rqp->nr_cs, &args->ioc_ncpbuf->cs, sizeof(rqp->nr_cs));
- copyout(&rqp->nr_cc, &args->ioc_ncpbuf->cc, sizeof(rqp->nr_cc));
- copyout(&rqp->nr_rpsize, &args->ioc_ncpbuf->rpsize, sizeof(rqp->nr_rpsize));
-bad:
- ncp_rq_done(rqp);
- return error;
-}
-
-static int
-ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
- struct thread *td, struct ucred *cred)
-{
- int error;
-
- if (ncp_suser(cred) != 0 && cred->cr_uid != conn->nc_owner->cr_uid)
- return EACCES;
- conn->li.user = ncp_str_dup(user);
- if (conn->li.user == NULL)
- return ENOMEM;
- conn->li.password = ncp_str_dup(password);
- if (conn->li.password == NULL) {
- error = ENOMEM;
- goto bad;
- }
- ncp_str_upper(conn->li.user);
- if ((conn->li.opt & NCP_OPT_NOUPCASEPASS) == 0)
- ncp_str_upper(conn->li.password);
- conn->li.objtype = objtype;
- error = ncp_conn_login(conn, td, cred);
- return error;
-bad:
- if (conn->li.user) {
- free(conn->li.user, M_NCPDATA);
- conn->li.user = NULL;
- }
- if (conn->li.password) {
- free(conn->li.password, M_NCPDATA);
- conn->li.password = NULL;
- }
- return error;
-}
-
-static int
-ncp_conn_handler(struct thread *td, struct ncpioc_request *args,
- struct ncp_conn *conn, struct ncp_handle *hp)
-{
- int error = 0, rqsize, subfn;
- struct ucred *cred;
-
- char *pdata;
-
- cred = td->td_ucred;
- error = copyin(&args->ioc_ncpbuf->rqsize, &rqsize, sizeof(int));
- if (error)
- return(error);
- error = 0;
- pdata = args->ioc_ncpbuf->packet;
- subfn = *(pdata++) & 0xff;
- rqsize--;
- switch (subfn) {
- case NCP_CONN_READ: case NCP_CONN_WRITE: {
- struct ncp_rw rwrq;
- struct uio auio;
- struct iovec iov;
-
- if (rqsize != sizeof(rwrq))
- return (EBADRPC);
- error = copyin(pdata,&rwrq,rqsize);
- if (error)
- return (error);
- iov.iov_base = rwrq.nrw_base;
- iov.iov_len = rwrq.nrw_cnt;
- auio.uio_iov = &iov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = rwrq.nrw_offset;
- auio.uio_resid = rwrq.nrw_cnt;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_rw = (subfn == NCP_CONN_READ) ? UIO_READ : UIO_WRITE;
- auio.uio_td = td;
- if (subfn == NCP_CONN_READ)
- error = ncp_read(conn, &rwrq.nrw_fh, &auio, cred);
- else
- error = ncp_write(conn, &rwrq.nrw_fh, &auio, cred);
- rwrq.nrw_cnt -= auio.uio_resid;
- /*td->td_retval[0] = rwrq.nrw_cnt;*/
- break;
- } /* case int_read/write */
- case NCP_CONN_SETFLAGS: {
- u_int16_t mask, flags;
-
- error = copyin(pdata,&mask, sizeof(mask));
- if (error)
- return error;
- pdata += sizeof(mask);
- error = copyin(pdata,&flags,sizeof(flags));
- if (error)
- return error;
- error = ncp_conn_lock(conn, td, cred, NCPM_WRITE);
- if (error)
- return error;
- if (mask & NCPFL_PERMANENT) {
- conn->flags &= ~NCPFL_PERMANENT;
- conn->flags |= (flags & NCPFL_PERMANENT);
- }
- if (mask & NCPFL_PRIMARY) {
- error = ncp_conn_setprimary(conn, flags & NCPFL_PRIMARY);
- if (error) {
- ncp_conn_unlock(conn, td);
- break;
- }
- }
- ncp_conn_unlock(conn, td);
- break;
- }
- case NCP_CONN_LOGIN: {
- struct ncp_conn_login la;
-
- if (rqsize != sizeof(la))
- return EBADRPC;
- if (conn->flags & NCPFL_LOGGED)
- return EALREADY;
- if ((error = copyin(pdata,&la,rqsize)) != 0)
- break;
- error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE | NCPM_WRITE);
- if (error)
- return error;
- error = ncp_mod_login(conn, la.username, la.objtype,
- la.password, td, td->td_ucred);
- ncp_conn_unlock(conn, td);
- break;
- }
- case NCP_CONN_GETINFO: {
- struct ncp_conn_stat ncs;
- int len = sizeof(ncs);
-
- error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
- if (error)
- return error;
- ncp_conn_getinfo(conn, &ncs);
- copyout(&len, &args->ioc_ncpbuf->rpsize, sizeof(int));
- error = copyout(&ncs, &args->ioc_ncpbuf->packet, len);
- ncp_conn_unlock(conn, td);
- break;
- }
- case NCP_CONN_GETUSER: {
- int len;
-
- error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
- if (error)
- return error;
- len = (conn->li.user) ? strlen(conn->li.user) + 1 : 0;
- copyout(&len, &args->ioc_ncpbuf->rpsize, sizeof(int));
- if (len) {
- error = copyout(conn->li.user,
- &args->ioc_ncpbuf->packet, len);
- }
- ncp_conn_unlock(conn, td);
- break;
- }
- case NCP_CONN_CONN2REF: {
- int len = sizeof(int);
-
- error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
- if (error)
- return error;
- copyout(&len, &args->ioc_ncpbuf->rpsize, sizeof(int));
- if (len) {
- error = copyout(&conn->nc_id,
- &args->ioc_ncpbuf->packet, len);
- }
- ncp_conn_unlock(conn, td);
- break;
- }
- case NCP_CONN_FRAG: {
- struct ncp_conn_frag nf;
-
- if (rqsize != sizeof(nf))
- return (EBADRPC);
- if ((error = copyin(pdata, &nf, rqsize)) != 0) break;
- error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE);
- if (error)
- return error;
- error = ncp_conn_frag_rq(conn, td, &nf);
- ncp_conn_unlock(conn, td);
- copyout(&nf, &pdata, sizeof(nf));
- td->td_retval[0] = error;
- break;
- }
- case NCP_CONN_DUP: {
- struct ncp_handle *newhp;
- int len = sizeof(NWCONN_HANDLE);
-
- error = ncp_conn_lock(conn, td, cred, NCPM_READ);
- if (error) break;
- copyout(&len, &args->ioc_ncpbuf->rpsize, len);
- error = ncp_conn_gethandle(conn, td, &newhp);
- if (!error)
- error = copyout(&newhp->nh_id,
- args->ioc_ncpbuf->packet, len);
- ncp_conn_unlock(conn, td);
- break;
- }
- case NCP_CONN_CONNCLOSE: {
- error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE);
- if (error) break;
- ncp_conn_puthandle(hp, td, 0);
- error = ncp_conn_free(conn);
- if (error)
- ncp_conn_unlock(conn, td);
- break;
- }
- default:
- error = EOPNOTSUPP;
- }
- return error;
-}
-
-static int
-sncp_conn_scan(struct thread *td, struct ncpioc_connscan *args)
-{
- int connHandle = 0, error;
- struct ncp_conn_args li, *lip;
- struct ncp_conn *conn;
- struct ncp_handle *hp;
- char *user = NULL, *password = NULL;
-
- if (args->ioc_li) {
- if (copyin(args->ioc_li, &li, sizeof(li)))
- return EFAULT;
- lip = &li;
- } else {
- lip = NULL;
- }
-
- if (lip != NULL) {
- lip->server[sizeof(lip->server)-1]=0; /* just to make sure */
- ncp_str_upper(lip->server);
- if (lip->user) {
- user = ncp_str_dup(lip->user);
- if (user == NULL)
- return EINVAL;
- ncp_str_upper(user);
- }
- if (lip->password) {
- password = ncp_str_dup(lip->password);
- if (password == NULL) {
- if (user)
- free(user, M_NCPDATA);
- return EINVAL;
- }
- ncp_str_upper(password);
- }
- lip->user = user;
- lip->password = password;
- }
- error = ncp_conn_getbyli(lip, td, td->td_ucred, NCPM_EXECUTE, &conn);
- if (!error) { /* already have this login */
- ncp_conn_gethandle(conn, td, &hp);
- connHandle = hp->nh_id;
- ncp_conn_unlock(conn, td);
- copyout(&connHandle, args->ioc_connhandle, sizeof(connHandle));
- }
- if (user)
- free(user, M_NCPDATA);
- if (password)
- free(password, M_NCPDATA);
- return error;
-
-}
-
-int
-ncp_conn_frag_rq(struct ncp_conn *conn, struct thread *td,
- struct ncp_conn_frag *nfp)
-{
- NW_FRAGMENT *fp;
- struct ncp_rq *rqp;
- u_int32_t fsize;
- int error, i, rpsize;
-
- error = ncp_rq_alloc(nfp->fn, conn, td, td->td_ucred, &rqp);
- if (error)
- return error;
- for(fp = nfp->rqf, i = 0; i < nfp->rqfcnt; i++, fp++) {
- error = mb_put_mem(&rqp->rq, (caddr_t)fp->fragAddress, fp->fragSize, MB_MUSER);
- if (error)
- goto bad;
- }
- rqp->nr_flags |= NCPR_DONTFREEONERR;
- error = ncp_request(rqp);
- if (error)
- goto bad;
- rpsize = rqp->nr_rpsize;
- if (rpsize && nfp->rpfcnt) {
- for(fp = nfp->rpf, i = 0; i < nfp->rpfcnt; i++, fp++) {
- error = copyin(&fp->fragSize, &fsize, sizeof (fsize));
- if (error)
- break;
- fsize = min(fsize, rpsize);
- error = md_get_mem(&rqp->rp, (caddr_t)fp->fragAddress, fsize, MB_MUSER);
- if (error)
- break;
- rpsize -= fsize;
- error = copyout(&fsize, &fp->fragSize, sizeof (fsize));
- if (error)
- break;
- }
- }
- nfp->cs = rqp->nr_cs;
- nfp->cc = rqp->nr_cc;
-bad:
- ncp_rq_done(rqp);
- return error;
-}
-
-static int
-ncp_load(void)
-{
- int error;
-
- if ((error = ncp_init()) != 0)
- return (error);
- ncp_dev = make_dev(&ncp_cdevsw, 0, 0, 0, 0666, "ncp");
- printf("ncp_load: loaded\n");
- return (0);
-}
-
-static int
-ncp_unload(void)
-{
- int error;
-
- error = ncp_done();
- if (error)
- return (error);
- destroy_dev(ncp_dev);
- printf("ncp_unload: unloaded\n");
- return (0);
-}
-
-static int
-ncp_mod_handler(module_t mod, int type, void *data)
-{
- int error;
-
- switch (type) {
- case MOD_LOAD:
- error = ncp_load();
- break;
- case MOD_UNLOAD:
- error = ncp_unload();
- break;
- default:
- error = EINVAL;
- }
- return error;
-}
-
-static moduledata_t ncp_mod = {
- "ncp",
- ncp_mod_handler,
- NULL
-};
-DECLARE_MODULE(ncp, ncp_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
OpenPOWER on IntegriCloud