Catch up with KSE changes.

Reviewed by:	tjr
This commit is contained in:
fjoe 2003-02-26 21:25:55 +00:00
parent f0bc886975
commit c7eeea06ec
11 changed files with 369 additions and 314 deletions

View File

@ -61,7 +61,7 @@ static int ncp_next_handle = 1;
static struct lock lhlock;
static int ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS);
static int ncp_conn_lock_any(struct ncp_conn *conn, struct proc *p,
static int ncp_conn_lock_any(struct ncp_conn *conn, struct thread *td,
struct ucred *cred);
SYSCTL_DECL(_net_ncp);
@ -93,15 +93,15 @@ ncp_conn_destroy(void)
}
int
ncp_conn_locklist(int flags, struct proc *p)
ncp_conn_locklist(int flags, struct thread *td)
{
return lockmgr(&listlock, flags | LK_CANRECURSE, 0, p);
return lockmgr(&listlock, flags | LK_CANRECURSE, 0, td);
}
void
ncp_conn_unlocklist(struct proc *p)
ncp_conn_unlocklist(struct thread *td)
{
lockmgr(&listlock, LK_RELEASE, 0, p);
lockmgr(&listlock, LK_RELEASE, 0, td);
}
int
@ -120,55 +120,55 @@ ncp_conn_access(struct ncp_conn *conn, struct ucred *cred, mode_t mode)
}
int
ncp_conn_lock_any(struct ncp_conn *conn, struct proc *p, struct ucred *cred)
ncp_conn_lock_any(struct ncp_conn *conn, struct thread *td, struct ucred *cred)
{
int error;
if (conn->nc_id == 0) return EACCES;
error = lockmgr(&conn->nc_lock, LK_EXCLUSIVE | LK_CANRECURSE, 0, p);
error = lockmgr(&conn->nc_lock, LK_EXCLUSIVE | LK_CANRECURSE, 0, td);
if (error == ERESTART)
return EINTR;
error = ncp_chkintr(conn, p);
error = ncp_chkintr(conn, td);
if (error) {
lockmgr(&conn->nc_lock, LK_RELEASE, 0, p);
lockmgr(&conn->nc_lock, LK_RELEASE, 0, td);
return error;
}
if (conn->nc_id == 0) {
lockmgr(&conn->nc_lock, LK_RELEASE, 0, p);
lockmgr(&conn->nc_lock, LK_RELEASE, 0, td);
return EACCES;
}
conn->procp = p; /* who currently operates */
conn->td = td; /* who currently operates */
conn->ucred = cred;
return 0;
}
int
ncp_conn_lock(struct ncp_conn *conn, struct proc *p, struct ucred *cred, int mode)
ncp_conn_lock(struct ncp_conn *conn, struct thread *td, struct ucred *cred, int mode)
{
int error;
error = ncp_conn_access(conn,cred,mode);
error = ncp_conn_access(conn, cred, mode);
if (error) return error;
return ncp_conn_lock_any(conn, p, cred);
return ncp_conn_lock_any(conn, td, cred);
}
/*
* Lock conn but unlock connlist
*/
static int
ncp_conn_lock2(struct ncp_conn *conn, struct proc *p, struct ucred *cred, int mode)
ncp_conn_lock2(struct ncp_conn *conn, struct thread *td, struct ucred *cred, int mode)
{
int error;
error = ncp_conn_access(conn,cred,mode);
error = ncp_conn_access(conn, cred, mode);
if (error) {
ncp_conn_unlocklist(p);
ncp_conn_unlocklist(td);
return error;
}
conn->nc_lwant++;
ncp_conn_unlocklist(p);
error = ncp_conn_lock_any(conn,p,cred);
ncp_conn_unlocklist(td);
error = ncp_conn_lock_any(conn, td, cred);
conn->nc_lwant--;
if (conn->nc_lwant == 0) {
wakeup(&conn->nc_lwant);
@ -177,17 +177,18 @@ ncp_conn_lock2(struct ncp_conn *conn, struct proc *p, struct ucred *cred, int mo
}
void
ncp_conn_unlock(struct ncp_conn *conn, struct proc *p)
ncp_conn_unlock(struct ncp_conn *conn, struct thread *td)
{
/*
* note, that LK_RELASE will do wakeup() instead of wakeup_one().
* this will do a little overhead
*/
lockmgr(&conn->nc_lock, LK_RELEASE, 0, p);
lockmgr(&conn->nc_lock, LK_RELEASE, 0, td);
}
int
ncp_conn_assert_locked(struct ncp_conn *conn,char *checker, struct proc *p){
int
ncp_conn_assert_locked(struct ncp_conn *conn, const char *checker, struct thread *td)
{
if (conn->nc_lock.lk_flags & LK_HAVE_EXCL) return 0;
printf("%s: connection isn't locked!\n", checker);
return EIO;
@ -205,11 +206,11 @@ ncp_conn_invalid(struct ncp_conn *ncp)
return ncp->flags & NCPFL_INVALID;
}
/*
/*
* create, fill with defaults and return in locked state
*/
int
ncp_conn_alloc(struct ncp_conn_args *cap, struct proc *p, struct ucred *cred,
ncp_conn_alloc(struct ncp_conn_args *cap, struct thread *td, struct ucred *cred,
struct ncp_conn **conn)
{
struct ncp_conn *ncp;
@ -242,18 +243,18 @@ ncp_conn_alloc(struct ncp_conn_args *cap, struct proc *p, struct ucred *cred,
ncp->seq = 0;
ncp->connid = 0xFFFF;
ncp->li = *cap;
ncp->nc_group = (cap->group != NCP_DEFAULT_GROUP) ?
ncp->nc_group = (cap->group != NCP_DEFAULT_GROUP) ?
cap->group : cred->cr_groups[0];
if (cap->retry_count == 0)
ncp->li.retry_count = NCP_RETRY_COUNT;
if (cap->timeout == 0)
ncp->li.timeout = NCP_RETRY_TIMEOUT;
ncp_conn_lock_any(ncp, p, ncp->nc_owner);
ncp_conn_lock_any(ncp, td, ncp->nc_owner);
*conn = ncp;
ncp_conn_locklist(LK_EXCLUSIVE, p);
ncp_conn_locklist(LK_EXCLUSIVE, td);
SLIST_INSERT_HEAD(&conn_list,ncp,nc_next);
ncp_conn_unlocklist(p);
ncp_conn_unlocklist(td);
return (error);
}
@ -263,7 +264,7 @@ ncp_conn_alloc(struct ncp_conn_args *cap, struct proc *p, struct ucred *cred,
int
ncp_conn_free(struct ncp_conn *ncp)
{
struct proc *p;
struct thread *td;
int error;
if (ncp == NULL) {
@ -274,8 +275,8 @@ ncp_conn_free(struct ncp_conn *ncp)
NCPERROR("nc_id == 0\n");
return EACCES;
}
p = ncp->procp;
error = ncp_conn_assert_locked(ncp, __func__, p);
td = ncp->td;
error = ncp_conn_assert_locked(ncp, __func__, td);
if (error)
return error;
if (ncp->ref_cnt != 0 || (ncp->flags & NCPFL_PERMANENT))
@ -291,20 +292,20 @@ ncp_conn_free(struct ncp_conn *ncp)
* Mark conn as dead and wait for other process
*/
ncp->nc_id = 0;
ncp_conn_unlock(ncp, p);
ncp_conn_unlock(ncp, td);
/*
* if signal is raised - how I do react ?
*/
lockmgr(&ncp->nc_lock, LK_DRAIN, 0, p);
lockmgr(&ncp->nc_lock, LK_DRAIN, 0, td);
lockdestroy(&ncp->nc_lock);
while (ncp->nc_lwant) {
printf("lwant = %d\n", ncp->nc_lwant);
tsleep(&ncp->nc_lwant, PZERO,"ncpdr",2*hz);
}
ncp_conn_locklist(LK_EXCLUSIVE, p);
ncp_conn_locklist(LK_EXCLUSIVE, td);
SLIST_REMOVE(&conn_list, ncp, ncp_conn, nc_next);
ncp_conn_cnt--;
ncp_conn_unlocklist(p);
ncp_conn_unlocklist(td);
if (ncp->li.user)
free(ncp->li.user, M_NCPDATA);
if (ncp->li.password)
@ -349,7 +350,7 @@ ncp_conn_reconnect(struct ncp_conn *ncp)
}
int
ncp_conn_login(struct ncp_conn *conn, struct proc *p, struct ucred *cred)
ncp_conn_login(struct ncp_conn *conn, struct thread *td, struct ucred *cred)
{
struct ncp_bindery_object user;
u_char ncp_key[8];
@ -359,36 +360,38 @@ ncp_conn_login(struct ncp_conn *conn, struct proc *p, struct ucred *cred)
if (error) {
printf("%s: Warning: use unencrypted login\n", __func__);
error = ncp_login_unencrypted(conn, conn->li.objtype,
conn->li.user, conn->li.password, p, cred);
conn->li.user, conn->li.password, td, cred);
} else {
error = ncp_get_bindery_object_id(conn, conn->li.objtype,
conn->li.user, &user, p, cred);
conn->li.user, &user, td, cred);
if (error)
return error;
error = ncp_login_encrypted(conn, &user, ncp_key,
conn->li.password, p, cred);
conn->li.password, td, cred);
}
if (!error)
conn->flags |= NCPFL_LOGGED | NCPFL_WASLOGGED;
return error;
}
/*
* Lookup connection by handle, return a locked conn descriptor
/*
* Lookup connection by handle, return a locked conn descriptor
*/
int
ncp_conn_getbyref(int ref,struct proc *p,struct ucred *cred, int mode, struct ncp_conn **connpp){
ncp_conn_getbyref(int ref, struct thread *td, struct ucred *cred, int mode,
struct ncp_conn **connpp)
{
struct ncp_conn *ncp;
int error=0;
int error = 0;
ncp_conn_locklist(LK_SHARED, p);
ncp_conn_locklist(LK_SHARED, td);
SLIST_FOREACH(ncp, &conn_list, nc_next)
if (ncp->nc_id == ref) break;
if (ncp == NULL) {
ncp_conn_unlocklist(p);
ncp_conn_unlocklist(td);
return(EBADF);
}
error = ncp_conn_lock2(ncp, p, cred, mode);
error = ncp_conn_lock2(ncp, td, cred, mode);
if (!error)
*connpp = ncp;
return (error);
@ -397,18 +400,20 @@ ncp_conn_getbyref(int ref,struct proc *p,struct ucred *cred, int mode, struct nc
* find attached, but not logged in connection to specified server
*/
int
ncp_conn_getattached(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int mode, struct ncp_conn **connpp){
struct ncp_conn *ncp, *ncp2=NULL;
ncp_conn_getattached(struct ncp_conn_args *li, struct thread *td,
struct ucred *cred, int mode, struct ncp_conn **connpp)
{
struct ncp_conn *ncp, *ncp2 = NULL;
int error = 0;
ncp_conn_locklist(LK_SHARED, p);
ncp_conn_locklist(LK_SHARED, td);
SLIST_FOREACH(ncp, &conn_list, nc_next) {
if ((ncp->flags & NCPFL_LOGGED) != 0 ||
strcmp(ncp->li.server,li->server) != 0 ||
strcmp(ncp->li.server,li->server) != 0 ||
ncp->li.saddr.sa_len != li->saddr.sa_len ||
bcmp(&ncp->li.saddr,&ncp->li.saddr,li->saddr.sa_len) != 0)
continue;
if (ncp_suser(cred) == 0 ||
if (ncp_suser(cred) == 0 ||
cred->cr_uid == ncp->nc_owner->cr_uid)
break;
error = ncp_conn_access(ncp,cred,mode);
@ -417,18 +422,18 @@ ncp_conn_getattached(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,
}
if (ncp == NULL) ncp = ncp2;
if (ncp == NULL) {
ncp_conn_unlocklist(p);
ncp_conn_unlocklist(td);
return(EBADF);
}
error = ncp_conn_lock2(ncp,p,cred,mode);
error = ncp_conn_lock2(ncp, td, cred, mode);
if (!error)
*connpp=ncp;
return (error);
}
/*
/*
* Lookup connection by server/user pair, return a locked conn descriptor.
* if li is NULL or server/user pair incomplete, try to select best connection
* if li is NULL or server/user pair incomplete, try to select best connection
* based on owner.
* Connection selected in next order:
* 1. Try to search conn with ucred owner, if li is NULL also find a primary
@ -437,13 +442,15 @@ ncp_conn_getattached(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,
*/
int
ncp_conn_getbyli(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int mode, struct ncp_conn **connpp){
struct ncp_conn *ncp, *ncp2=NULL;
int error=0, partial, haveserv;
ncp_conn_getbyli(struct ncp_conn_args *li, struct thread *td,
struct ucred *cred, int mode, struct ncp_conn **connpp)
{
struct ncp_conn *ncp, *ncp2 = NULL;
int error = 0, partial, haveserv;
partial = (li == NULL || li->server[0] == 0 || li->user == NULL);
haveserv = (li && li->server[0]);
ncp_conn_locklist(LK_SHARED, p);
ncp_conn_locklist(LK_SHARED, td);
SLIST_FOREACH(ncp, &conn_list, nc_next) {
if (partial) {
if (cred->cr_uid == ncp->nc_owner->cr_uid) {
@ -473,10 +480,10 @@ ncp_conn_getbyli(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int
}
if (ncp == NULL) ncp = ncp2;
if (ncp == NULL) {
ncp_conn_unlocklist(p);
ncp_conn_unlocklist(td);
return(EBADF);
}
error = ncp_conn_lock2(ncp,p,cred,mode);
error = ncp_conn_lock2(ncp, td, cred,mode);
if (!error)
*connpp=ncp;
return (error);
@ -488,59 +495,62 @@ ncp_conn_getbyli(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int
* connection expected to be locked.
*/
int
ncp_conn_setprimary(struct ncp_conn *conn, int on){
ncp_conn_setprimary(struct ncp_conn *conn, int on)
{
struct ncp_conn *ncp=NULL;
if (conn->ucred->cr_uid != conn->nc_owner->cr_uid)
return EACCES;
ncp_conn_locklist(LK_SHARED, conn->procp);
ncp_conn_locklist(LK_SHARED, conn->td);
SLIST_FOREACH(ncp, &conn_list, nc_next) {
if (conn->ucred->cr_uid == ncp->nc_owner->cr_uid)
ncp->flags &= ~NCPFL_PRIMARY;
}
ncp_conn_unlocklist(conn->procp);
ncp_conn_unlocklist(conn->td);
if (on)
conn->flags |= NCPFL_PRIMARY;
return 0;
}
/*
/*
* Lease conn to given proc, returning unique handle
* problem: how locks should be applied ?
*/
int
ncp_conn_gethandle(struct ncp_conn *conn, struct proc *p, struct ncp_handle **handle){
ncp_conn_gethandle(struct ncp_conn *conn, struct thread *td, struct ncp_handle **handle)
{
struct ncp_handle *refp;
lockmgr(&lhlock, LK_EXCLUSIVE, 0, p);
lockmgr(&lhlock, LK_EXCLUSIVE, 0, td);
SLIST_FOREACH(refp, &lhlist, nh_next)
if (refp->nh_conn == conn && p == refp->nh_proc) break;
if (refp->nh_conn == conn && td == refp->nh_td) break;
if (refp) {
conn->ref_cnt++;
refp->nh_ref++;
*handle = refp;
lockmgr(&lhlock, LK_RELEASE, 0, p);
lockmgr(&lhlock, LK_RELEASE, 0, td);
return 0;
}
MALLOC(refp,struct ncp_handle *,sizeof(struct ncp_handle),M_NCPDATA,
M_WAITOK | M_ZERO);
SLIST_INSERT_HEAD(&lhlist,refp,nh_next);
refp->nh_ref++;
refp->nh_proc = p;
refp->nh_td = td;
refp->nh_conn = conn;
refp->nh_id = ncp_next_handle++;
*handle = refp;
conn->ref_cnt++;
lockmgr(&lhlock, LK_RELEASE, 0, p);
lockmgr(&lhlock, LK_RELEASE, 0, td);
return 0;
}
/*
* release reference, if force - ignore refcount
*/
int
ncp_conn_puthandle(struct ncp_handle *handle, struct proc *p, int force) {
ncp_conn_puthandle(struct ncp_handle *handle, struct thread *td, int force)
{
struct ncp_handle *refp = handle;
lockmgr(&lhlock, LK_EXCLUSIVE, 0, p);
lockmgr(&lhlock, LK_EXCLUSIVE, 0, td);
refp->nh_ref--;
refp->nh_conn->ref_cnt--;
if (force) {
@ -551,20 +561,20 @@ ncp_conn_puthandle(struct ncp_handle *handle, struct proc *p, int force) {
SLIST_REMOVE(&lhlist, refp, ncp_handle, nh_next);
FREE(refp, M_NCPDATA);
}
lockmgr(&lhlock, LK_RELEASE, 0, p);
lockmgr(&lhlock, LK_RELEASE, 0, td);
return 0;
}
/*
* find a connHandle
*/
int
ncp_conn_findhandle(int connHandle, struct proc *p, struct ncp_handle **handle) {
ncp_conn_findhandle(int connHandle, struct thread *td, struct ncp_handle **handle) {
struct ncp_handle *refp;
lockmgr(&lhlock, LK_SHARED, 0, p);
lockmgr(&lhlock, LK_SHARED, 0, td);
SLIST_FOREACH(refp, &lhlist, nh_next)
if (refp->nh_proc == p && refp->nh_id == connHandle) break;
lockmgr(&lhlock, LK_RELEASE, 0, p);
if (refp->nh_td == td && refp->nh_id == connHandle) break;
lockmgr(&lhlock, LK_RELEASE, 0, td);
if (refp == NULL) {
return EBADF;
}
@ -575,20 +585,21 @@ ncp_conn_findhandle(int connHandle, struct proc *p, struct ncp_handle **handle)
* Clear handles associated with specified process
*/
int
ncp_conn_putprochandles(struct proc *p) {
ncp_conn_putprochandles(struct thread *td)
{
struct ncp_handle *hp, *nhp;
int haveone = 0;
lockmgr(&lhlock, LK_EXCLUSIVE, 0, p);
lockmgr(&lhlock, LK_EXCLUSIVE, 0, td);
for (hp = SLIST_FIRST(&lhlist); hp; hp = nhp) {
nhp = SLIST_NEXT(hp, nh_next);
if (hp->nh_proc != p) continue;
if (hp->nh_td != td) continue;
haveone = 1;
hp->nh_conn->ref_cnt -= hp->nh_ref;
SLIST_REMOVE(&lhlist, hp, ncp_handle, nh_next);
FREE(hp, M_NCPDATA);
}
lockmgr(&lhlock, LK_RELEASE, 0, p);
lockmgr(&lhlock, LK_RELEASE, 0, td);
return haveone;
}
/*
@ -626,7 +637,8 @@ ncp_conn_getinfo(struct ncp_conn *ncp, struct ncp_conn_stat *ncs) {
}
static int
ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS) {
ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS)
{
int error;
struct ncp_conn_stat ncs;
struct ncp_conn *ncp;
@ -634,7 +646,7 @@ ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS) {
error = 0;
sysctl_wire_old_buffer(req, 0);
ncp_conn_locklist(LK_SHARED, req->p);
ncp_conn_locklist(LK_SHARED, req->td);
error = SYSCTL_OUT(req, &ncp_conn_cnt, sizeof(ncp_conn_cnt));
SLIST_FOREACH(ncp, &conn_list, nc_next) {
if (error) break;
@ -650,6 +662,6 @@ ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS) {
ncp->nc_lwant--;
error = SYSCTL_OUT(req, &ncs, sizeof(ncs));
}
ncp_conn_unlocklist(req->p);
ncp_conn_unlocklist(req->td);
return(error);
}

View File

@ -132,7 +132,7 @@ struct ncp_conn_stat {
#ifdef _KERNEL
#ifndef LK_SHARED
#include <sys/lock.h>
#include <sys/lockmgr.h>
#endif
struct socket;
@ -151,7 +151,7 @@ struct ncp_handle {
SLIST_ENTRY(ncp_handle) nh_next;
int nh_id; /* handle id */
struct ncp_conn*nh_conn; /* which conn we are refernce */
struct proc * nh_proc; /* who owns the handle */
struct thread * nh_td; /* who owns the handle */
int nh_ref; /* one process can asquire many handles, but we return the one */
};
@ -173,7 +173,7 @@ struct ncp_conn {
SLIST_HEAD(ncp_ref_hd,ncp_ref) ref_list;/* list of handles */
struct lock nc_lock; /* excl locks */
int nc_lwant; /* number of wanted locks */
struct proc *procp; /* pid currently operates */
struct thread *td; /* pid currently operates */
struct ucred *ucred; /* usr currently operates */
/* Fields used to process ncp requests */
int connid; /* assigned by server */
@ -200,7 +200,7 @@ int ncp_conn_free(struct ncp_conn *conn);
int ncp_conn_access(struct ncp_conn *conn,struct ucred *cred,mode_t mode);
int ncp_conn_lock(struct ncp_conn *conn,struct thread *td, struct ucred *cred,int mode);
void ncp_conn_unlock(struct ncp_conn *conn,struct thread *td);
int ncp_conn_assert_locked(struct ncp_conn *conn,char *checker,struct thread *td);
int ncp_conn_assert_locked(struct ncp_conn *conn,const char *checker,struct thread *td);
void ncp_conn_invalidate(struct ncp_conn *ncp);
int ncp_conn_invalid(struct ncp_conn *ncp);
/*int ncp_conn_ref(struct ncp_conn *conn, pid_t pid);

View File

@ -37,6 +37,7 @@
#include <sys/sysent.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/syscall.h>
#include <sys/sysctl.h>
#include <sys/malloc.h>
#include <sys/uio.h>
@ -61,7 +62,8 @@ MODULE_VERSION(ncp, 1);
MODULE_DEPEND(ncp, libmchain, 1, 1, 1);
static int
ncp_conn_frag_rq(struct ncp_conn *conn, struct proc *p, struct ncp_conn_frag *nfp);
ncp_conn_frag_rq(struct ncp_conn *conn, struct thread *td,
struct ncp_conn_frag *nfp);
/*
* Attach to NCP server
@ -71,8 +73,8 @@ struct sncp_connect_args {
int *connHandle;
};
static int
sncp_connect(struct proc *p, struct sncp_connect_args *uap)
static int
sncp_connect(struct thread *td, struct sncp_connect_args *uap)
{
int connHandle = 0, error;
struct ncp_conn *conn;
@ -82,9 +84,9 @@ sncp_connect(struct proc *p, struct sncp_connect_args *uap)
checkbad(copyin(uap->li,&li,sizeof(li)));
checkbad(copyout(&connHandle,uap->connHandle,sizeof(connHandle))); /* check before */
li.password = li.user = NULL;
error = ncp_conn_getattached(&li, p, p->p_ucred, NCPM_WRITE | NCPM_EXECUTE, &conn);
error = ncp_conn_getattached(&li, td, td->td_ucred, NCPM_WRITE | NCPM_EXECUTE, &conn);
if (error) {
error = ncp_conn_alloc(&li, p, p->p_ucred, &conn);
error = ncp_conn_alloc(&li, td, td->td_ucred, &conn);
if (error)
goto bad;
error = ncp_conn_reconnect(conn);
@ -92,12 +94,12 @@ sncp_connect(struct proc *p, struct sncp_connect_args *uap)
ncp_conn_free(conn);
}
if (!error) {
error = ncp_conn_gethandle(conn, p, &handle);
error = ncp_conn_gethandle(conn, td, &handle);
copyout(&handle->nh_id, uap->connHandle, sizeof(uap->connHandle));
ncp_conn_unlock(conn,p);
ncp_conn_unlock(conn,td);
}
bad:
p->p_retval[0]=error;
td->td_retval[0]=error;
return error;
}
@ -107,27 +109,27 @@ struct sncp_request_args {
struct ncp_buf *ncpbuf;
};
static int ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
static int ncp_conn_handler(struct thread *td, struct sncp_request_args *uap,
struct ncp_conn *conn, struct ncp_handle *handle);
static int
sncp_request(struct proc *p, struct sncp_request_args *uap)
sncp_request(struct thread *td, struct sncp_request_args *uap)
{
struct ncp_rq *rqp;
struct ncp_conn *conn;
struct ncp_handle *handle;
int error = 0, rqsize;
error = ncp_conn_findhandle(uap->connHandle,p,&handle);
error = ncp_conn_findhandle(uap->connHandle, td, &handle);
if (error)
return error;
conn = handle->nh_conn;
if (uap->fn == NCP_CONN)
return ncp_conn_handler(p, uap, conn, handle);
return ncp_conn_handler(td, uap, conn, handle);
error = copyin(&uap->ncpbuf->rqsize, &rqsize, sizeof(int));
if (error)
return(error);
error = ncp_rq_alloc(uap->fn, conn, p, p->p_ucred, &rqp);
error = ncp_rq_alloc(uap->fn, conn, td, td->td_ucred, &rqp);
if (error)
return error;
if (rqsize) {
@ -151,7 +153,7 @@ sncp_request(struct proc *p, struct sncp_request_args *uap)
static int
ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
struct proc *p, struct ucred *cred)
struct thread *td, struct ucred *cred)
{
int error;
@ -169,7 +171,7 @@ ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
if ((conn->li.opt & NCP_OPT_NOUPCASEPASS) == 0)
ncp_str_upper(conn->li.password);
conn->li.objtype = objtype;
error = ncp_conn_login(conn, p, cred);
error = ncp_conn_login(conn, td, cred);
return error;
bad:
if (conn->li.user) {
@ -184,17 +186,18 @@ ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
}
static int
ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
ncp_conn_handler(struct thread *td, struct sncp_request_args *uap,
struct ncp_conn *conn, struct ncp_handle *hp)
{
int error=0, rqsize, subfn;
int error = 0, rqsize, subfn;
struct ucred *cred;
char *pdata;
cred = p->p_ucred;
cred = td->td_ucred;
error = copyin(&uap->ncpbuf->rqsize, &rqsize, sizeof(int));
if (error) return(error);
if (error)
return(error);
error = 0;
pdata = uap->ncpbuf->packet;
subfn = *(pdata++) & 0xff;
@ -204,10 +207,12 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
struct ncp_rw rwrq;
struct uio auio;
struct iovec iov;
if (rqsize != sizeof(rwrq)) return (EBADRPC);
if (rqsize != sizeof(rwrq))
return (EBADRPC);
error = copyin(pdata,&rwrq,rqsize);
if (error) return (error);
if (error)
return (error);
iov.iov_base = rwrq.nrw_base;
iov.iov_len = rwrq.nrw_cnt;
auio.uio_iov = &iov;
@ -216,25 +221,28 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
auio.uio_resid = rwrq.nrw_cnt;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = (subfn == NCP_CONN_READ) ? UIO_READ : UIO_WRITE;
auio.uio_procp = p;
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;
p->p_retval[0] = rwrq.nrw_cnt;
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;
if (error)
return error;
pdata += sizeof(mask);
error = copyin(pdata,&flags,sizeof(flags));
if (error) return error;
error = ncp_conn_lock(conn,p,cred,NCPM_WRITE);
if (error) return error;
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);
@ -242,11 +250,11 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
if (mask & NCPFL_PRIMARY) {
error = ncp_conn_setprimary(conn, flags & NCPFL_PRIMARY);
if (error) {
ncp_conn_unlock(conn,p);
ncp_conn_unlock(conn, td);
break;
}
}
ncp_conn_unlock(conn,p);
ncp_conn_unlock(conn, td);
break;
}
case NCP_CONN_LOGIN: {
@ -258,83 +266,90 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
return EALREADY;
if ((error = copyin(pdata,&la,rqsize)) != 0)
break;
error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE | NCPM_WRITE);
if (error) return error;
error = ncp_mod_login(conn, la.username, la.objtype, la.password, p, p->p_ucred);
ncp_conn_unlock(conn, p);
p->p_retval[0] = error;
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);
td->td_retval[0] = error;
break;
}
case NCP_CONN_GETINFO: {
struct ncp_conn_stat ncs;
int len = sizeof(ncs);
error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
if (error) return error;
error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
if (error)
return error;
ncp_conn_getinfo(conn, &ncs);
copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
error = copyout(&ncs, &uap->ncpbuf->packet, len);
ncp_conn_unlock(conn, p);
ncp_conn_unlock(conn, td);
break;
}
case NCP_CONN_GETUSER: {
int len;
error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
if (error) return error;
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, &uap->ncpbuf->rpsize, sizeof(int));
if (len) {
error = copyout(conn->li.user, &uap->ncpbuf->packet, len);
}
ncp_conn_unlock(conn, p);
ncp_conn_unlock(conn, td);
break;
}
case NCP_CONN_CONN2REF: {
int len = sizeof(int);
error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
if (error) return error;
error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
if (error)
return error;
copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
if (len) {
error = copyout(&conn->nc_id, &uap->ncpbuf->packet, len);
}
ncp_conn_unlock(conn, p);
ncp_conn_unlock(conn, td);
break;
}
case NCP_CONN_FRAG: {
struct ncp_conn_frag nf;
if (rqsize != sizeof(nf)) return (EBADRPC);
if (rqsize != sizeof(nf))
return (EBADRPC);
if ((error = copyin(pdata, &nf, rqsize)) != 0) break;
error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE);
if (error) return error;
error = ncp_conn_frag_rq(conn, p, &nf);
ncp_conn_unlock(conn, p);
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));
p->p_retval[0] = error;
td->td_retval[0] = error;
break;
}
case NCP_CONN_DUP: {
struct ncp_handle *newhp;
int len = sizeof(NWCONN_HANDLE);
error = ncp_conn_lock(conn, p, cred, NCPM_READ);
error = ncp_conn_lock(conn, td, cred, NCPM_READ);
if (error) break;
copyout(&len, &uap->ncpbuf->rpsize, len);
error = ncp_conn_gethandle(conn, p, &newhp);
error = ncp_conn_gethandle(conn, td, &newhp);
if (!error)
error = copyout(&newhp->nh_id, uap->ncpbuf->packet, len);
ncp_conn_unlock(conn,p);
ncp_conn_unlock(conn, td);
break;
}
case NCP_CONN_CONNCLOSE: {
error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE);
error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE);
if (error) break;
ncp_conn_puthandle(hp, p, 0);
ncp_conn_puthandle(hp, td, 0);
error = ncp_conn_free(conn);
if (error)
ncp_conn_unlock(conn, p);
ncp_conn_unlock(conn, td);
break;
}
default:
@ -348,8 +363,8 @@ struct sncp_conn_scan_args {
int *connHandle;
};
static int
sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
static int
sncp_conn_scan(struct thread *td, struct sncp_conn_scan_args *uap)
{
int connHandle = 0, error;
struct ncp_conn_args li, *lip;
@ -358,7 +373,8 @@ sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
char *user = NULL, *password = NULL;
if (uap->li) {
if (copyin(uap->li,&li,sizeof(li))) return EFAULT;
if (copyin(uap->li, &li, sizeof(li)))
return EFAULT;
lip = &li;
} else {
lip = NULL;
@ -369,7 +385,8 @@ sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
ncp_str_upper(lip->server);
if (lip->user) {
user = ncp_str_dup(lip->user);
if (user == NULL) return EINVAL;
if (user == NULL)
return EINVAL;
ncp_str_upper(user);
}
if (lip->password) {
@ -384,29 +401,32 @@ sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
lip->user = user;
lip->password = password;
}
error = ncp_conn_getbyli(lip,p,p->p_ucred,NCPM_EXECUTE,&conn);
if (!error) { /* already have this login */
ncp_conn_gethandle(conn, p, &hp);
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,p);
copyout(&connHandle,uap->connHandle,sizeof(connHandle));
ncp_conn_unlock(conn, td);
copyout(&connHandle, uap->connHandle, sizeof(connHandle));
}
if (user) free(user, M_NCPDATA);
if (password) free(password, M_NCPDATA);
p->p_retval[0] = error;
if (user)
free(user, M_NCPDATA);
if (password)
free(password, M_NCPDATA);
td->td_retval[0] = error;
return error;
}
int
ncp_conn_frag_rq(struct ncp_conn *conn, struct proc *p, struct ncp_conn_frag *nfp)
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, p, p->p_ucred, &rqp);
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++) {
@ -456,17 +476,19 @@ sncp_intfn(struct proc *p, struct sncp_intfn_args *uap)
{
return ENOSYS;
}
/*
* define our new system calls
*/
static struct sysent newent[] = {
{2, (sy_call_t*)sncp_conn_scan},
{2, (sy_call_t*)sncp_conn_scan},
{2, (sy_call_t*)sncp_connect},
{2, (sy_call_t*)sncp_intfn},
{3, (sy_call_t*)sncp_request}
};
#define SC_SIZE sizeof(newent)/sizeof(struct sysent)
/*
* Miscellaneous modules must have their own save areas...
*/
@ -475,44 +497,47 @@ static struct sysent oldent[SC_SIZE]; /* save are for old callslot entry*/
/*
* Number of syscall entries for a.out executables
*/
/*#define nsysent SYS_MAXSYSCALL*/
#define nsysent (aout_sysvec.sv_size)
#define nsysent SYS_MAXSYSCALL
/* #define nsysent (elf_sysvec.sv_size) */
static int
ncp_load(void) {
int i, ff, scnt, err=0;
ncp_load(void)
{
int i, ff, scnt, err = 0;
while(1) {
while (1) {
/* Search the table looking for an enough number of slots... */
for (scnt=0, ff = -1, i = 0; i < nsysent; i++) {
for (scnt = 0, ff = -1, i = 0; i < nsysent; i++) {
if (sysent[i].sy_call == (sy_call_t *)lkmnosys) {
if (ff == -1) {
ff = i;
scnt = 1;
ff = i;
scnt = 1;
} else {
scnt++;
if (scnt == SC_SIZE) break;
scnt++;
if (scnt == SC_SIZE)
break;
}
} else {
ff = -1;
}
}
/* out of allocable slots?*/
if(i == nsysent || ff == -1) {
if (i == nsysent || ff == -1) {
err = ENFILE;
break;
}
err = ncp_init();
if (err) break;
bcopy(&sysent[ff], &oldent, sizeof(struct sysent)*SC_SIZE);
bcopy(&newent, &sysent[ff], sizeof(struct sysent)*SC_SIZE);
if (err)
break;
bcopy(&sysent[ff], &oldent, sizeof(struct sysent) * SC_SIZE);
bcopy(&newent, &sysent[ff], sizeof(struct sysent) * SC_SIZE);
ncp_sysent = ff; /* slot in sysent[]*/
printf("ncp_load: [%d-%d]\n",ff,i);
printf("ncp_load: [%d-%d]\n", ff, i);
break;
}
return( err);
return (err);
}
static int
@ -534,18 +559,18 @@ ncp_mod_handler(module_t mod, int type, void *data)
int error;
switch (type) {
case MOD_LOAD:
case MOD_LOAD:
error = ncp_load();
break;
case MOD_UNLOAD:
case MOD_UNLOAD:
error = ncp_unload();
break;
default:
default:
error = EINVAL;
}
return error;
}
\
static moduledata_t ncp_mod = {
"ncp",
ncp_mod_handler,

View File

@ -41,6 +41,8 @@
#include <sys/signalvar.h>
#include <sys/sysctl.h>
#include <sys/mbuf.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/uio.h>
#include <netipx/ipx.h>
@ -74,12 +76,14 @@ void m_dumpm(struct mbuf *m) {
#endif /* NCP_DATA_DEBUG */
int
ncp_chkintr(struct ncp_conn *conn, struct proc *p)
ncp_chkintr(struct ncp_conn *conn, struct thread *td)
{
struct proc *p;
sigset_t tmpset;
if (p == NULL)
if (td == NULL)
return 0;
p = td->td_proc;
PROC_LOCK(p);
tmpset = p->p_siglist;
SIGSETNAND(tmpset, p->p_sigmask);
@ -103,8 +107,8 @@ ncp_ncp_connect(struct ncp_conn *conn)
struct ncp_rq *rqp;
struct ncp_rphdr *rp;
int error;
error = ncp_rq_alloc_any(NCP_ALLOC_SLOT, 0, conn, conn->procp, conn->ucred, &rqp);
error = ncp_rq_alloc_any(NCP_ALLOC_SLOT, 0, conn, conn->td, conn->ucred, &rqp);
if (error)
return error;
@ -134,7 +138,7 @@ ncp_ncp_disconnect(struct ncp_conn *conn)
ncp_burst_disconnect(conn);
#endif
if (conn->flags & NCPFL_ATTACHED) {
error = ncp_rq_alloc_any(NCP_FREE_SLOT, 0, conn, conn->procp, conn->ucred, &rqp);
error = ncp_rq_alloc_any(NCP_FREE_SLOT, 0, conn, conn->td, conn->ucred, &rqp);
if (!error) {
ncp_request_int(rqp);
ncp_rq_done(rqp);
@ -156,7 +160,7 @@ ncp_negotiate_buffersize(struct ncp_conn *conn, int size, int *target)
u_int16_t bsize;
int error;
error = ncp_rq_alloc(0x21, conn, conn->procp, conn->ucred, &rqp);
error = ncp_rq_alloc(0x21, conn, conn->td, conn->ucred, &rqp);
if (error)
return error;
mb_put_uint16be(&rqp->rq, size);
@ -170,14 +174,14 @@ ncp_negotiate_buffersize(struct ncp_conn *conn, int size, int *target)
}
static int
ncp_negotiate_size_and_options(struct ncp_conn *conn, int size, int options,
ncp_negotiate_size_and_options(struct ncp_conn *conn, int size, int options,
int *ret_size, u_int8_t *ret_options)
{
struct ncp_rq *rqp;
u_int16_t rs;
int error;
error = ncp_rq_alloc(0x61, conn, conn->procp, conn->ucred, &rqp);
error = ncp_rq_alloc(0x61, conn, conn->td, conn->ucred, &rqp);
if (error)
return error;
mb_put_uint16be(&rqp->rq, size);
@ -205,14 +209,14 @@ ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize, u_int8_t in_optio
in_options |= NCP_SECURITY_LEVEL_SIGN_HEADERS;
if (conn->li.saddr.sa_family == AF_IPX) {
ilen = sizeof(ckslevel);
error = kernel_sysctlbyname(curproc, "net.ipx.ipx.checksum",
error = kernel_sysctlbyname(curthread, "net.ipx.ipx.checksum",
&ckslevel, &ilen, NULL, 0, NULL);
if (error)
return error;
if (ckslevel == 2)
in_options |= NCP_IPX_CHECKSUM;
}
error = ncp_negotiate_size_and_options(conn, buffsize, in_options,
error = ncp_negotiate_size_and_options(conn, buffsize, in_options,
&neg_buffsize, &options);
if (!error) {
if (conn->li.saddr.sa_family == AF_IPX &&
@ -256,26 +260,27 @@ ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize, u_int8_t in_optio
}
void
ncp_check_rq(struct ncp_conn *conn){
ncp_check_rq(struct ncp_conn *conn)
{
return;
if (conn->flags & NCPFL_INTR) return;
if (conn->flags & NCPFL_INTR)
return;
/* first, check for signals */
if (ncp_chkintr(conn,conn->procp)) {
if (ncp_chkintr(conn, conn->td))
conn->flags |= NCPFL_INTR;
}
return;
}
int
ncp_get_bindery_object_id(struct ncp_conn *conn,
u_int16_t object_type, char *object_name,
ncp_get_bindery_object_id(struct ncp_conn *conn,
u_int16_t object_type, char *object_name,
struct ncp_bindery_object *target,
struct proc *p,struct ucred *cred)
struct thread *td, struct ucred *cred)
{
struct ncp_rq *rqp;
int error;
error = ncp_rq_alloc_subfn(23, 53, conn, conn->procp, conn->ucred, &rqp);
error = ncp_rq_alloc_subfn(23, 53, conn, conn->td, conn->ucred, &rqp);
mb_put_uint16be(&rqp->rq, object_type);
ncp_rq_pstring(rqp, object_name);
rqp->nr_minrplen = 54;
@ -298,7 +303,7 @@ ncp_get_encryption_key(struct ncp_conn *conn, char *target)
struct ncp_rq *rqp;
int error;
error = ncp_rq_alloc_subfn(23, 23, conn, conn->procp, conn->ucred, &rqp);
error = ncp_rq_alloc_subfn(23, 23, conn, conn->td, conn->ucred, &rqp);
if (error)
return error;
rqp->nr_minrplen = 8;
@ -340,7 +345,7 @@ ncp_sign_start(struct ncp_conn *conn, char *logindata)
int
ncp_login_encrypted(struct ncp_conn *conn, struct ncp_bindery_object *object,
const u_char *key, const u_char *passwd,
struct proc *p, struct ucred *cred)
struct thread *td, struct ucred *cred)
{
struct ncp_rq *rqp;
struct mbchain *mbp;
@ -352,7 +357,7 @@ ncp_login_encrypted(struct ncp_conn *conn, struct ncp_bindery_object *object,
nw_keyhash((u_char*)&tmpID, passwd, strlen(passwd), buf);
nw_encrypt(key, buf, encrypted);
error = ncp_rq_alloc_subfn(23, 24, conn, p, cred, &rqp);
error = ncp_rq_alloc_subfn(23, 24, conn, td, cred, &rqp);
if (error)
return error;
mbp = &rqp->rq;
@ -371,14 +376,14 @@ ncp_login_encrypted(struct ncp_conn *conn, struct ncp_bindery_object *object,
}
int
ncp_login_unencrypted(struct ncp_conn *conn, u_int16_t object_type,
ncp_login_unencrypted(struct ncp_conn *conn, u_int16_t object_type,
const char *object_name, const u_char *passwd,
struct proc *p, struct ucred *cred)
struct thread *td, struct ucred *cred)
{
struct ncp_rq *rqp;
int error;
error = ncp_rq_alloc_subfn(23, 20, conn, p, cred, &rqp);
error = ncp_rq_alloc_subfn(23, 20, conn, td, cred, &rqp);
if (error)
return error;
mb_put_uint16be(&rqp->rq, object_type);
@ -409,7 +414,7 @@ ncp_read(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cr
if (!burstio) {
len = min(4096 - (uiop->uio_offset % 4096), tsiz);
len = min(len, conn->buffer_size);
error = ncp_rq_alloc(72, conn, uiop->uio_procp, cred, &rqp);
error = ncp_rq_alloc(72, conn, uiop->uio_td, cred, &rqp);
if (error)
break;
mbp = &rqp->rq;
@ -459,7 +464,7 @@ ncp_write(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *c
printf("gotcha!\n");
}
/* rq head */
error = ncp_rq_alloc(73, conn, uiop->uio_procp, cred, &rqp);
error = ncp_rq_alloc(73, conn, uiop->uio_td, cred, &rqp);
if (error)
break;
mbp = &rqp->rq;

View File

@ -108,7 +108,6 @@ struct ncp_bursthdr {
struct ncp_conn;
struct ncp_conn_args;
struct ncp_rq;
struct proc;
struct ucred;
int ncp_ncp_connect(struct ncp_conn *conn);
@ -119,15 +118,15 @@ int ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize,
int ncp_get_bindery_object_id(struct ncp_conn *conn,
u_int16_t object_type, char *object_name,
struct ncp_bindery_object *target,
struct proc *p,struct ucred *cred);
struct thread *td,struct ucred *cred);
int ncp_get_encryption_key(struct ncp_conn *conn, char *target);
int ncp_login_encrypted(struct ncp_conn *conn,
struct ncp_bindery_object *object,
const u_char *key, const u_char *passwd,
struct proc *p, struct ucred *cred);
struct thread *td, struct ucred *cred);
int ncp_login_unencrypted(struct ncp_conn *conn, u_int16_t object_type,
const char *object_name, const u_char *passwd,
struct proc *p, struct ucred *cred);
struct thread *td, struct ucred *cred);
int ncp_read(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred);
int ncp_write(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred);

View File

@ -57,14 +57,14 @@ static int ncp_sign_packet(struct ncp_conn *conn, struct ncp_rq *rqp, int *size)
int
ncp_rq_alloc_any(u_int32_t ptype, u_int8_t fn, struct ncp_conn *ncp,
struct proc *p, struct ucred *cred,
struct thread *td, struct ucred *cred,
struct ncp_rq **rqpp)
{
struct ncp_rq *rqp;
int error;
MALLOC(rqp, struct ncp_rq *, sizeof(*rqp), M_NCPRQ, M_WAITOK);
error = ncp_rq_init_any(rqp, ptype, fn, ncp, p, cred);
error = ncp_rq_init_any(rqp, ptype, fn, ncp, td, cred);
rqp->nr_flags |= NCPR_ALLOCED;
if (error) {
ncp_rq_done(rqp);
@ -76,19 +76,19 @@ ncp_rq_alloc_any(u_int32_t ptype, u_int8_t fn, struct ncp_conn *ncp,
int
ncp_rq_alloc(u_int8_t fn, struct ncp_conn *ncp,
struct proc *p, struct ucred *cred, struct ncp_rq **rqpp)
struct thread *td, struct ucred *cred, struct ncp_rq **rqpp)
{
return ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, p, cred, rqpp);
return ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, td, cred, rqpp);
}
int
ncp_rq_alloc_subfn(u_int8_t fn, u_int8_t subfn, struct ncp_conn *ncp,
struct proc *p, struct ucred *cred, struct ncp_rq **rqpp)
struct thread *td, struct ucred *cred, struct ncp_rq **rqpp)
{
struct ncp_rq *rqp;
int error;
error = ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, p, cred, &rqp);
error = ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, td, cred, &rqp);
if (error)
return error;
mb_reserve(&rqp->rq, 2);
@ -100,7 +100,7 @@ ncp_rq_alloc_subfn(u_int8_t fn, u_int8_t subfn, struct ncp_conn *ncp,
int
ncp_rq_init_any(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,
struct ncp_conn *ncp,
struct proc *p, struct ucred *cred)
struct thread *td, struct ucred *cred)
{
struct ncp_rqhdr *rq;
struct ncp_bursthdr *brq;
@ -111,7 +111,7 @@ ncp_rq_init_any(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,
error = ncp_conn_access(ncp, cred, NCPM_EXECUTE);
if (error)
return error;
rqp->nr_p = p;
rqp->nr_td = td;
rqp->nr_cred = cred;
rqp->nr_conn = ncp;
mbp = &rqp->rq;
@ -239,11 +239,11 @@ ncp_sign_packet(struct ncp_conn *conn, struct ncp_rq *rqp, int *size)
* Low level send rpc, here we do not attempt to restore any connection,
* Connection expected to be locked
*/
int
int
ncp_request_int(struct ncp_rq *rqp)
{
struct ncp_conn *conn = rqp->nr_conn;
struct proc *p = conn->procp;
struct thread *td = conn->td;
struct socket *so = conn->ncp_so;
struct ncp_rqhdr *rq;
struct ncp_rphdr *rp=NULL;
@ -257,8 +257,8 @@ ncp_request_int(struct ncp_rq *rqp)
ncp_conn_invalidate(conn);
return ENOTCONN;
}
if (p == NULL)
p = curproc; /* XXX maybe procpage ? */
if (td == NULL)
td = curthread; /* XXX maybe procpage ? */
/*
* Flush out replies on previous reqs
*/
@ -307,10 +307,10 @@ ncp_request_int(struct ncp_rq *rqp)
}
tv.tv_sec = conn->li.timeout;
tv.tv_usec = 0;
error = ncp_sock_rselect(so, p, &tv, POLLIN);
error = ncp_sock_rselect(so, td, &tv, POLLIN);
if (error == EWOULDBLOCK ) /* timeout expired */
continue;
error = ncp_chkintr(conn, p);
error = ncp_chkintr(conn, td);
if (error)
break;
/*
@ -422,7 +422,7 @@ ncp_restore_login(struct ncp_conn *conn)
conn->flags |= NCPFL_RESTORING;
error = ncp_conn_reconnect(conn);
if (!error && (conn->flags & NCPFL_WASLOGGED))
error = ncp_conn_login(conn, conn->procp, conn->ucred);
error = ncp_conn_login(conn, conn->td, conn->ucred);
if (error)
ncp_ncp_disconnect(conn);
conn->flags &= ~NCPFL_RESTORING;
@ -435,7 +435,7 @@ ncp_request(struct ncp_rq *rqp)
struct ncp_conn *ncp = rqp->nr_conn;
int error, rcnt;
error = ncp_conn_lock(ncp, rqp->nr_p, rqp->nr_cred, NCPM_EXECUTE);
error = ncp_conn_lock(ncp, rqp->nr_td, rqp->nr_cred, NCPM_EXECUTE);
if (error)
goto out;
rcnt = NCP_RESTORE_COUNT;
@ -460,7 +460,7 @@ ncp_request(struct ncp_rq *rqp)
if (error)
continue;
}
ncp_conn_unlock(ncp, rqp->nr_p);
ncp_conn_unlock(ncp, rqp->nr_td);
out:
if (error && (rqp->nr_flags & NCPR_DONTFREEONERR) == 0)
ncp_rq_done(rqp);

View File

@ -52,11 +52,6 @@
#define setdle(buf,ofs,val) getdle(buf,ofs)=val
#define setdbe(buf,ofs,val) getdle(buf,ofs)=htonl(val)
#define htoles(x) ((u_int16_t)(x))
#define letohs(x) ((u_int16_t)(x))
#define htolel(x) ((u_int32_t)(x))
#define letohl(x) ((u_int32_t)(x))
#else
#error "Macros for Big-Endians are incomplete"
#define getwle(buf,ofs) ((u_int16_t)(getb(buf, ofs) | (getb(buf, ofs + 1) << 8)))

View File

@ -66,17 +66,19 @@
/*int ncp_poll(struct socket *so, int events);*/
/*static int ncp_getsockname(struct socket *so, caddr_t asa, int *alen);*/
static int ncp_soconnect(struct socket *so,struct sockaddr *target, struct proc *p);
static int ncp_soconnect(struct socket *so, struct sockaddr *target,
struct thread *td);
/* This will need only if native IP used, or (unlikely) NCP will be
* implemented on the socket level
*/
static int
ncp_soconnect(struct socket *so,struct sockaddr *target, struct proc *p) {
int error,s;
ncp_soconnect(struct socket *so, struct sockaddr *target, struct thread *td)
{
int error, s;
error = soconnect(so, (struct sockaddr*)target, p);
error = soconnect(so, (struct sockaddr*)target, td);
if (error)
return error;
/*
@ -129,11 +131,11 @@ ncp_getsockname(struct socket *so, caddr_t asa, int *alen) {
int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen)
{
struct uio auio;
struct proc *p=curproc; /* XXX */
struct thread *td = curthread; /* XXX */
int error,flags,len;
auio.uio_resid = len = 1000000;
auio.uio_procp = p;
auio.uio_td = td;
flags = MSG_DONTWAIT;
/* error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, &auio,
@ -155,23 +157,23 @@ int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen)
int
ncp_sock_send(struct socket *so, struct mbuf *top, struct ncp_rq *rqp)
{
struct proc *p = curproc; /* XXX */
struct thread *td = curthread; /* XXX */
struct sockaddr *to = 0;
struct ncp_conn *conn = rqp->nr_conn;
struct mbuf *m;
int error, flags=0;
int sendwait;
for(;;) {
for (;;) {
m = m_copym(top, 0, M_COPYALL, M_TRYWAIT);
/* NCPDDEBUG(m);*/
error = so->so_proto->pr_usrreqs->pru_sosend(so, to, 0, m, 0, flags, p);
error = so->so_proto->pr_usrreqs->pru_sosend(so, to, 0, m, 0, flags, td);
if (error == 0 || error == EINTR || error == ENETDOWN)
break;
if (rqp->rexmit == 0) break;
rqp->rexmit--;
tsleep(&sendwait, PWAIT, "ncprsn", conn->li.timeout * hz);
error = ncp_chkintr(conn, p);
error = ncp_chkintr(conn, td);
if (error == EINTR) break;
}
if (error) {
@ -181,20 +183,23 @@ ncp_sock_send(struct socket *so, struct mbuf *top, struct ncp_rq *rqp)
}
int
ncp_poll(struct socket *so, int events){
struct proc *p = curproc;
struct ucred *cred=NULL;
return so->so_proto->pr_usrreqs->pru_sopoll(so, events, cred, p);
ncp_poll(struct socket *so, int events)
{
struct thread *td = curthread;
struct ucred *cred = NULL;
return so->so_proto->pr_usrreqs->pru_sopoll(so, events, cred, td);
}
int
ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv, int events)
ncp_sock_rselect(struct socket *so, struct thread *td, struct timeval *tv,
int events)
{
struct timeval atv,rtv,ttv;
int timo,error=0;
struct timeval atv, rtv, ttv;
int ncoll, timo, error = 0;
if (tv) {
atv=*tv;
atv = *tv;
if (itimerfix(&atv)) {
error = EINVAL;
goto done_noproclock;
@ -203,56 +208,65 @@ ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv, int event
timevaladd(&atv, &rtv);
}
timo = 0;
PROC_LOCK(p);
p->p_flag |= P_SELECT;
PROC_UNLOCK(p);
mtx_lock(&sellock);
retry:
ncoll = nselcoll;
mtx_lock_spin(&sched_lock);
td->td_flags |= TDF_SELECT;
mtx_unlock_spin(&sched_lock);
mtx_unlock(&sellock);
TAILQ_INIT(&td->td_selq);
error = ncp_poll(so, events);
PROC_LOCK(p);
mtx_lock(&sellock);
if (error) {
error = 0;
goto done;
}
if (tv) {
getmicrouptime(&rtv);
if (timevalcmp(&rtv, &atv, >=)) {
/*
* An event of our interest may occur during locking a process.
* In order to avoid missing the event that occured during locking
* the process, test P_SELECT and rescan file descriptors if
* necessary.
*/
if ((p->p_flag & P_SELECT) == 0) {
p->p_flag |= P_SELECT;
PROC_UNLOCK(p);
error = ncp_poll(so, events);
PROC_LOCK(p);
}
if (timevalcmp(&rtv, &atv, >=))
goto done;
}
ttv=atv;
ttv = atv;
timevalsub(&ttv, &rtv);
timo = tvtohz(&ttv);
}
p->p_flag &= ~P_SELECT;
/*
* An event of our interest may occur during locking a thread.
* In order to avoid missing the event that occurred during locking
* the process, test TDF_SELECT and rescan file descriptors if
* necessary.
*/
mtx_lock_spin(&sched_lock);
if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
mtx_unlock_spin(&sched_lock);
goto retry;
}
mtx_unlock_spin(&sched_lock);
if (timo > 0)
error = cv_timedwait(&selwait, &p->p_mtx, timo);
error = cv_timedwait(&selwait, &sellock, timo);
else {
cv_wait(&selwait, &p->p_mtx);
cv_wait(&selwait, &sellock);
error = 0;
}
done:
p->p_flag &= ~P_SELECT;
PROC_UNLOCK(p);
clear_selinfo_list(td);
mtx_lock_spin(&sched_lock);
td->td_flags &= ~TDF_SELECT;
mtx_unlock_spin(&sched_lock);
mtx_unlock(&sellock);
done_noproclock:
if (error == ERESTART) {
/* printf("Signal: %x", cursig(p));*/
if (error == ERESTART)
error = 0;
}
return (error);
}
/*
/*
* Connect to specified server via IPX
*/
static int
@ -260,7 +274,7 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
{
struct sockaddr_ipx sipx;
struct ipxpcb *npcb;
struct proc *p = conn->procp;
struct thread *td = conn->td;
int addrlen, error, count;
sipx.sipx_port = htons(0);
@ -271,15 +285,15 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
goto bad;
}
conn->ncp_so = conn->wdg_so = NULL;
checkbad(socreate(AF_IPX, &conn->ncp_so, SOCK_DGRAM, 0, p));
checkbad(socreate(AF_IPX, &conn->ncp_so, SOCK_DGRAM, 0, td->td_ucred, td));
if (conn->li.opt & NCP_OPT_WDOG)
checkbad(socreate(AF_IPX, &conn->wdg_so, SOCK_DGRAM,0,p));
checkbad(socreate(AF_IPX, &conn->wdg_so, SOCK_DGRAM, 0, td->td_ucred, td));
addrlen = sizeof(sipx);
sipx.sipx_family = AF_IPX;
ipx_setnullnet(sipx.sipx_addr);
ipx_setnullhost(sipx.sipx_addr);
sipx.sipx_len = addrlen;
error = sobind(conn->ncp_so, (struct sockaddr *)&sipx, p);
error = sobind(conn->ncp_so, (struct sockaddr *)&sipx, td);
if (error == 0) {
if ((conn->li.opt & NCP_OPT_WDOG) == 0)
break;
@ -287,7 +301,7 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
sipx.sipx_port = htons(ntohs(sipx.sipx_port) + 1);
ipx_setnullnet(sipx.sipx_addr);
ipx_setnullhost(sipx.sipx_addr);
error = sobind(conn->wdg_so, (struct sockaddr *)&sipx, p);
error = sobind(conn->wdg_so, (struct sockaddr *)&sipx, td);
}
if (!error) break;
if (error != EADDRINUSE) goto bad;
@ -300,7 +314,7 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
npcb->ipxp_dpt = IPXPROTO_NCP;
/* IPXrouted must be running, i.e. route must be presented */
conn->li.ipxaddr.sipx_len = sizeof(struct sockaddr_ipx);
checkbad(ncp_soconnect(conn->ncp_so, &conn->li.saddr, p));
checkbad(ncp_soconnect(conn->ncp_so, &conn->li.saddr, td));
if (conn->wdg_so) {
sotoipxpcb(conn->wdg_so)->ipxp_laddr.x_net = npcb->ipxp_laddr.x_net;
sotoipxpcb(conn->wdg_so)->ipxp_laddr.x_host= npcb->ipxp_laddr.x_host;
@ -310,11 +324,11 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
}
#ifdef NCPBURST
if (ncp_burst_enabled) {
checkbad(socreate(AF_IPX, &conn->bc_so, SOCK_DGRAM, 0, p));
checkbad(socreate(AF_IPX, &conn->bc_so, SOCK_DGRAM, 0, td));
bzero(&sipx, sizeof(sipx));
sipx.sipx_len = sizeof(sipx);
checkbad(sobind(conn->bc_so, (struct sockaddr *)&sipx, p));
checkbad(ncp_soconnect(conn->bc_so, &conn->li.saddr, p));
checkbad(sobind(conn->bc_so, (struct sockaddr *)&sipx, td));
checkbad(ncp_soconnect(conn->bc_so, &conn->li.saddr, td));
}
#endif
if (!error) {
@ -339,24 +353,24 @@ ncp_sock_checksum(struct ncp_conn *conn, int enable)
return 0;
}
/*
/*
* Connect to specified server via IP
*/
static int
ncp_sock_connect_in(struct ncp_conn *conn)
{
struct sockaddr_in sin;
struct proc *p=conn->procp;
int addrlen=sizeof(sin), error;
struct thread *td = conn->td;
int addrlen = sizeof(sin), error;
conn->flags = 0;
bzero(&sin,addrlen);
conn->ncp_so = conn->wdg_so = NULL;
checkbad(socreate(AF_INET, &conn->ncp_so, SOCK_DGRAM, IPPROTO_UDP, p));
checkbad(socreate(AF_INET, &conn->ncp_so, SOCK_DGRAM, IPPROTO_UDP, td->td_ucred, td));
sin.sin_family = AF_INET;
sin.sin_len = addrlen;
checkbad(sobind(conn->ncp_so, (struct sockaddr *)&sin, p));
checkbad(ncp_soconnect(conn->ncp_so,(struct sockaddr*)&conn->li.addr, p));
checkbad(sobind(conn->ncp_so, (struct sockaddr *)&sin, td));
checkbad(ncp_soconnect(conn->ncp_so,(struct sockaddr*)&conn->li.addr, td));
if (!error)
conn->flags |= NCPFL_SOCONN;
return error;
@ -426,9 +440,9 @@ ncp_watchdog(struct ncp_conn *conn) {
while (conn->wdg_so) { /* not a loop */
so = conn->wdg_so;
auio.uio_resid = len = 1000000;
auio.uio_procp = curproc;
auio.uio_td = curthread;
flags = MSG_DONTWAIT;
error = so->so_proto->pr_usrreqs->pru_soreceive(so,
error = so->so_proto->pr_usrreqs->pru_soreceive(so,
(struct sockaddr**)&sa, &auio, &m, (struct mbuf**)0, &flags);
if (error) break;
len -= auio.uio_resid;
@ -437,7 +451,7 @@ ncp_watchdog(struct ncp_conn *conn) {
buf = mtod(m, char*);
if (buf[1] != '?') break;
buf[1] = 'Y';
error = so->so_proto->pr_usrreqs->pru_sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curproc);
error = so->so_proto->pr_usrreqs->pru_sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curthread);
NCPSDEBUG("send watch dog %d\n",error);
break;
}

View File

@ -46,7 +46,8 @@ int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen);
int ncp_sock_send(struct socket *so, struct mbuf *data, struct ncp_rq *rqp);
int ncp_sock_disconnect(struct ncp_conn *conn);
int ncp_poll(struct socket *so, int events);
int ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv,int events);
int ncp_sock_rselect(struct socket *so, struct thread *td, struct timeval *tv,
int events);
int ncp_sock_checksum(struct ncp_conn *conn, int enable);
void ncp_check_rq(struct ncp_conn *conn);

View File

@ -79,19 +79,23 @@ void
ncp_at_exit(struct proc *p)
{
struct ncp_conn *ncp, *nncp;
struct thread *td;
if (ncp_conn_putprochandles(p) == 0) return;
ncp_conn_locklist(LK_EXCLUSIVE, p);
for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) {
nncp = SLIST_NEXT(ncp, nc_next);
if (ncp_conn_lock(ncp, p, p->p_ucred,NCPM_READ|NCPM_EXECUTE|NCPM_WRITE))
FOREACH_THREAD_IN_PROC(p, td) {
if (ncp_conn_putprochandles(td) == 0)
continue;
if (ncp_conn_free(ncp) != 0)
ncp_conn_unlock(ncp,p);
ncp_conn_locklist(LK_EXCLUSIVE, td);
for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) {
nncp = SLIST_NEXT(ncp, nc_next);
if (ncp_conn_lock(ncp, td, td->td_ucred,
NCPM_READ | NCPM_EXECUTE | NCPM_WRITE))
continue;
if (ncp_conn_free(ncp) != 0)
ncp_conn_unlock(ncp, td);
}
ncp_conn_unlocklist(td);
}
ncp_conn_unlocklist(p);
return;
}
int
@ -102,7 +106,7 @@ ncp_init(void)
NCPFATAL("can't register at_exit handler\n");
return ENOMEM;
}
ncp_timer_handle = timeout(ncp_timer,NULL,NCP_TIMER_TICK);
ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
return 0;
}
@ -114,7 +118,7 @@ ncp_done(void)
error = ncp_conn_destroy();
if (error)
return error;
untimeout(ncp_timer,NULL,ncp_timer_handle);
untimeout(ncp_timer, NULL, ncp_timer_handle);
rm_at_exit(ncp_at_exit);
return 0;
}
@ -131,5 +135,5 @@ ncp_timer(void *arg)
ncp_check_conn(conn);
ncp_conn_unlocklist(NULL);
}
ncp_timer_handle = timeout(ncp_timer,NULL,NCP_TIMER_TICK);
ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
}

View File

@ -111,7 +111,7 @@ struct ucred;
int ncp_init(void);
int ncp_done(void);
int ncp_chkintr(struct ncp_conn *conn, struct proc *p);
int ncp_chkintr(struct ncp_conn *conn, struct thread *td);
char*ncp_str_dup(char *s);
/* ncp_crypt.c */