Fix panic due to page faults while in kernel mode, under conditions of

VM pressure. The reason is that in some codepaths pointers to stack
variables were passed from one thread to another.

In collaboration with:	pho
Reported by:	pho's stress2 suite
Sponsored by:	iXsystems inc.
This commit is contained in:
Davide Italiano 2012-10-31 03:34:07 +00:00
parent 994f027fbc
commit afe097512c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=242386
11 changed files with 419 additions and 220 deletions

View file

@ -75,7 +75,7 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
{ {
struct dirent de; struct dirent de;
struct componentname cn; struct componentname cn;
struct smb_cred scred; struct smb_cred *scred;
struct smbfs_fctx *ctx; struct smbfs_fctx *ctx;
struct vnode *newvp; struct vnode *newvp;
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
@ -84,11 +84,14 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
np = VTOSMB(vp); np = VTOSMB(vp);
SMBVDEBUG("dirname='%s'\n", np->n_name); SMBVDEBUG("dirname='%s'\n", np->n_name);
smb_makescred(&scred, uio->uio_td, cred); scred = smbfs_malloc_scred();
smb_makescred(scred, uio->uio_td, cred);
offset = uio->uio_offset / DE_SIZE; /* offset in the directory */ offset = uio->uio_offset / DE_SIZE; /* offset in the directory */
limit = uio->uio_resid / DE_SIZE; limit = uio->uio_resid / DE_SIZE;
if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) {
return EINVAL; error = EINVAL;
goto out;
}
while (limit && offset < 2) { while (limit && offset < 2) {
limit--; limit--;
bzero((caddr_t)&de, DE_SIZE); bzero((caddr_t)&de, DE_SIZE);
@ -104,40 +107,43 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
de.d_type = DT_DIR; de.d_type = DT_DIR;
error = uiomove(&de, DE_SIZE, uio); error = uiomove(&de, DE_SIZE, uio);
if (error) if (error)
return error; goto out;
offset++; offset++;
uio->uio_offset += DE_SIZE; uio->uio_offset += DE_SIZE;
} }
if (limit == 0) if (limit == 0) {
return 0; error = 0;
goto out;
}
if (offset != np->n_dirofs || np->n_dirseq == NULL) { if (offset != np->n_dirofs || np->n_dirseq == NULL) {
SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs); SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs);
if (np->n_dirseq) { if (np->n_dirseq) {
smbfs_findclose(np->n_dirseq, &scred); smbfs_findclose(np->n_dirseq, scred);
np->n_dirseq = NULL; np->n_dirseq = NULL;
} }
np->n_dirofs = 2; np->n_dirofs = 2;
error = smbfs_findopen(np, "*", 1, error = smbfs_findopen(np, "*", 1,
SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR,
&scred, &ctx); scred, &ctx);
if (error) { if (error) {
SMBVDEBUG("can not open search, error = %d", error); SMBVDEBUG("can not open search, error = %d", error);
return error; goto out;
} }
np->n_dirseq = ctx; np->n_dirseq = ctx;
} else } else
ctx = np->n_dirseq; ctx = np->n_dirseq;
while (np->n_dirofs < offset) { while (np->n_dirofs < offset) {
error = smbfs_findnext(ctx, offset - np->n_dirofs++, &scred); error = smbfs_findnext(ctx, offset - np->n_dirofs++, scred);
if (error) { if (error) {
smbfs_findclose(np->n_dirseq, &scred); smbfs_findclose(np->n_dirseq, scred);
np->n_dirseq = NULL; np->n_dirseq = NULL;
return error == ENOENT ? 0 : error; error = ENOENT ? 0 : error;
goto out;
} }
} }
error = 0; error = 0;
for (; limit; limit--, offset++) { for (; limit; limit--, offset++) {
error = smbfs_findnext(ctx, limit, &scred); error = smbfs_findnext(ctx, limit, scred);
if (error) if (error)
break; break;
np->n_dirofs++; np->n_dirofs++;
@ -165,6 +171,8 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
if (error == ENOENT) if (error == ENOENT)
error = 0; error = 0;
uio->uio_offset = offset * DE_SIZE; uio->uio_offset = offset * DE_SIZE;
out:
smbfs_free_scred(scred);
return error; return error;
} }
@ -175,7 +183,7 @@ smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred)
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct thread *td; struct thread *td;
struct vattr vattr; struct vattr vattr;
struct smb_cred scred; struct smb_cred *scred;
int error, lks; int error, lks;
/* /*
@ -223,8 +231,11 @@ smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred)
np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
} }
} }
smb_makescred(&scred, td, cred); scred = smbfs_malloc_scred();
return smb_read(smp->sm_share, np->n_fid, uiop, &scred); smb_makescred(scred, td, cred);
error = smb_read(smp->sm_share, np->n_fid, uiop, scred);
smbfs_free_scred(scred);
return (error);
} }
int int
@ -233,7 +244,7 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop,
{ {
struct smbmount *smp = VTOSMBFS(vp); struct smbmount *smp = VTOSMBFS(vp);
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct smb_cred scred; struct smb_cred *scred;
struct thread *td; struct thread *td;
int error = 0; int error = 0;
@ -272,9 +283,11 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop,
if (vn_rlimit_fsize(vp, uiop, td)) if (vn_rlimit_fsize(vp, uiop, td))
return (EFBIG); return (EFBIG);
smb_makescred(&scred, td, cred); scred = smbfs_malloc_scred();
error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); smb_makescred(scred, td, cred);
error = smb_write(smp->sm_share, np->n_fid, uiop, scred);
smbfs_free_scred(scred);
SMBVDEBUG("after: ofs=%jd,resid=%zd\n", (intmax_t)uiop->uio_offset, SMBVDEBUG("after: ofs=%jd,resid=%zd\n", (intmax_t)uiop->uio_offset,
uiop->uio_resid); uiop->uio_resid);
if (!error) { if (!error) {
@ -294,17 +307,19 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
{ {
struct smbmount *smp = VFSTOSMBFS(vp->v_mount); struct smbmount *smp = VFSTOSMBFS(vp->v_mount);
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct uio uio, *uiop = &uio; struct uio *uiop;
struct iovec io; struct iovec io;
struct smb_cred scred; struct smb_cred *scred;
int error = 0; int error = 0;
uiop = malloc(sizeof(struct uio), M_SMBFSDATA, M_WAITOK);
uiop->uio_iov = &io; uiop->uio_iov = &io;
uiop->uio_iovcnt = 1; uiop->uio_iovcnt = 1;
uiop->uio_segflg = UIO_SYSSPACE; uiop->uio_segflg = UIO_SYSSPACE;
uiop->uio_td = td; uiop->uio_td = td;
smb_makescred(&scred, td, cr); scred = smbfs_malloc_scred();
smb_makescred(scred, td, cr);
if (bp->b_iocmd == BIO_READ) { if (bp->b_iocmd == BIO_READ) {
io.iov_len = uiop->uio_resid = bp->b_bcount; io.iov_len = uiop->uio_resid = bp->b_bcount;
@ -313,7 +328,7 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
switch (vp->v_type) { switch (vp->v_type) {
case VREG: case VREG:
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
error = smb_read(smp->sm_share, np->n_fid, uiop, &scred); error = smb_read(smp->sm_share, np->n_fid, uiop, scred);
if (error) if (error)
break; break;
if (uiop->uio_resid) { if (uiop->uio_resid) {
@ -340,7 +355,7 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff; uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
uiop->uio_rw = UIO_WRITE; uiop->uio_rw = UIO_WRITE;
error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); error = smb_write(smp->sm_share, np->n_fid, uiop, scred);
/* /*
* For an interrupted write, the buffer is still valid * For an interrupted write, the buffer is still valid
@ -380,11 +395,15 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td
} else { } else {
bp->b_resid = 0; bp->b_resid = 0;
bufdone(bp); bufdone(bp);
free(uiop, M_SMBFSDATA);
smbfs_free_scred(scred);
return 0; return 0;
} }
} }
bp->b_resid = uiop->uio_resid; bp->b_resid = uiop->uio_resid;
bufdone(bp); bufdone(bp);
free(uiop, M_SMBFSDATA);
smbfs_free_scred(scred);
return error; return error;
} }
@ -415,7 +434,7 @@ smbfs_getpages(ap)
struct ucred *cred; struct ucred *cred;
struct smbmount *smp; struct smbmount *smp;
struct smbnode *np; struct smbnode *np;
struct smb_cred scred; struct smb_cred *scred;
vm_object_t object; vm_object_t object;
vm_page_t *pages, m; vm_page_t *pages, m;
@ -455,7 +474,8 @@ smbfs_getpages(ap)
} }
VM_OBJECT_UNLOCK(object); VM_OBJECT_UNLOCK(object);
smb_makescred(&scred, td, cred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, cred);
bp = getpbuf(&smbfs_pbuf_freecnt); bp = getpbuf(&smbfs_pbuf_freecnt);
@ -474,7 +494,8 @@ smbfs_getpages(ap)
uio.uio_rw = UIO_READ; uio.uio_rw = UIO_READ;
uio.uio_td = td; uio.uio_td = td;
error = smb_read(smp->sm_share, np->n_fid, &uio, &scred); error = smb_read(smp->sm_share, np->n_fid, &uio, scred);
smbfs_free_scred(scred);
pmap_qremove(kva, npages); pmap_qremove(kva, npages);
relpbuf(bp, &smbfs_pbuf_freecnt); relpbuf(bp, &smbfs_pbuf_freecnt);
@ -570,7 +591,7 @@ smbfs_putpages(ap)
int *rtvals; int *rtvals;
struct smbmount *smp; struct smbmount *smp;
struct smbnode *np; struct smbnode *np;
struct smb_cred scred; struct smb_cred *scred;
vm_page_t *pages; vm_page_t *pages;
td = curthread; /* XXX */ td = curthread; /* XXX */
@ -606,8 +627,10 @@ smbfs_putpages(ap)
SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uio.uio_offset, SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uio.uio_offset,
uio.uio_resid); uio.uio_resid);
smb_makescred(&scred, td, cred); scred = smbfs_malloc_scred();
error = smb_write(smp->sm_share, np->n_fid, &uio, &scred); smb_makescred(scred, td, cred);
error = smb_write(smp->sm_share, np->n_fid, &uio, scred);
smbfs_free_scred(scred);
/* VOP_CLOSE(vp, FWRITE, cred, td);*/ /* VOP_CLOSE(vp, FWRITE, cred, td);*/
SMBVDEBUG("paged write done: %d\n", error); SMBVDEBUG("paged write done: %d\n", error);

View file

@ -349,25 +349,27 @@ smbfs_inactive(ap)
struct ucred *cred = td->td_ucred; struct ucred *cred = td->td_ucred;
struct vnode *vp = ap->a_vp; struct vnode *vp = ap->a_vp;
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct smb_cred scred; struct smb_cred *scred;
struct vattr va; struct vattr va;
SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vrefcnt(vp)); SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vrefcnt(vp));
if ((np->n_flag & NOPEN) != 0) { if ((np->n_flag & NOPEN) != 0) {
smb_makescred(&scred, td, cred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, cred);
smbfs_vinvalbuf(vp, td); smbfs_vinvalbuf(vp, td);
if (vp->v_type == VREG) { if (vp->v_type == VREG) {
VOP_GETATTR(vp, &va, cred); VOP_GETATTR(vp, &va, cred);
smbfs_smb_close(np->n_mount->sm_share, np->n_fid, smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
&np->n_mtime, &scred); &np->n_mtime, scred);
} else if (vp->v_type == VDIR) { } else if (vp->v_type == VDIR) {
if (np->n_dirseq != NULL) { if (np->n_dirseq != NULL) {
smbfs_findclose(np->n_dirseq, &scred); smbfs_findclose(np->n_dirseq, scred);
np->n_dirseq = NULL; np->n_dirseq = NULL;
} }
} }
np->n_flag &= ~NOPEN; np->n_flag &= ~NOPEN;
smbfs_attr_cacheremove(vp); smbfs_attr_cacheremove(vp);
smbfs_free_scred(scred);
} }
if (np->n_flag & NGONE) if (np->n_flag & NGONE)
vrecycle(vp); vrecycle(vp);

View file

@ -87,16 +87,19 @@ smbfs_smb_lockandx(struct smbnode *np, int op, u_int32_t pid, off_t start, off_t
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct mbchain *mbp; struct mbchain *mbp;
u_char ltype = 0; u_char ltype = 0;
int error; int error;
if (op == SMB_LOCK_SHARED) if (op == SMB_LOCK_SHARED)
ltype |= SMB_LOCKING_ANDX_SHARED_LOCK; ltype |= SMB_LOCKING_ANDX_SHARED_LOCK;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_LOCKING_ANDX, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_LOCKING_ANDX, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_uint8(mbp, 0xff); /* secondary command */ mb_put_uint8(mbp, 0xff); /* secondary command */
@ -116,6 +119,7 @@ smbfs_smb_lockandx(struct smbnode *np, int op, u_int32_t pid, off_t start, off_t
smb_rq_bend(rqp); smb_rq_bend(rqp);
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -179,20 +183,24 @@ int
smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp, smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct mdchain *mdp; struct mdchain *mdp;
u_int16_t units, bpu, bsize, funits; u_int16_t units, bpu, bsize, funits;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION_DISK, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION_DISK, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
smb_rq_wend(rqp); smb_rq_wend(rqp);
smb_rq_bstart(rqp); smb_rq_bstart(rqp);
smb_rq_bend(rqp); smb_rq_bend(rqp);
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
if (error) { if (error) {
free(rqp, M_SMBFSDATA);
smb_rq_done(rqp); smb_rq_done(rqp);
return error; return error;
} }
@ -208,6 +216,7 @@ smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
sbp->f_files = 0xffff; /* total file nodes in filesystem */ sbp->f_files = 0xffff; /* total file nodes in filesystem */
sbp->f_ffree = 0xffff; /* free file nodes in fs */ sbp->f_ffree = 0xffff; /* free file nodes in fs */
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return 0; return 0;
} }
@ -244,16 +253,19 @@ static int
smb_smb_flush(struct smbnode *np, struct smb_cred *scred) smb_smb_flush(struct smbnode *np, struct smb_cred *scred)
{ {
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
if ((np->n_flag & NOPEN) == 0 || !SMBTOV(np) || if ((np->n_flag & NOPEN) == 0 || !SMBTOV(np) ||
SMBTOV(np)->v_type != VREG) SMBTOV(np)->v_type != VREG)
return 0; /* not a regular open file */ return 0; /* not a regular open file */
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_FLUSH, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_FLUSH, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return (error); return (error);
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM); mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
@ -262,6 +274,7 @@ smb_smb_flush(struct smbnode *np, struct smb_cred *scred)
smb_rq_bend(rqp); smb_rq_bend(rqp);
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
if (!error) if (!error)
np->n_flag &= ~NFLUSHWIRE; np->n_flag &= ~NFLUSHWIRE;
return (error); return (error);
@ -279,7 +292,7 @@ int
smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred) smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
{ {
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
@ -288,9 +301,12 @@ smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
return (0); return (0);
} }
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_WRITE, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_WRITE, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM); mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
@ -304,6 +320,7 @@ smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
smb_rq_bend(rqp); smb_rq_bend(rqp);
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -311,7 +328,7 @@ int
smbfs_smb_query_info(struct smbnode *np, const char *name, int len, smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
struct smbfattr *fap, struct smb_cred *scred) struct smbfattr *fap, struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
struct mdchain *mdp; struct mdchain *mdp;
@ -320,9 +337,12 @@ smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
u_int16_t wattr; u_int16_t wattr;
u_int32_t lint; u_int32_t lint;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
smb_rq_wend(rqp); smb_rq_wend(rqp);
@ -357,6 +377,7 @@ smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
fap->fa_size = lint; fap->fa_size = lint;
} while(0); } while(0);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -367,15 +388,18 @@ int
smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime, smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
u_long time; u_long time;
int error, svtz; int error, svtz;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
svtz = SSTOVC(ssp)->vc_sopt.sv_tz; svtz = SSTOVC(ssp)->vc_sopt.sv_tz;
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
@ -407,6 +431,7 @@ smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
} }
} while(0); } while(0);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -523,15 +548,18 @@ int
smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime, smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime,
struct timespec *atime, struct smb_cred *scred) struct timespec *atime, struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
u_int16_t date, time; u_int16_t date, time;
int error, tzoff; int error, tzoff;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION2, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION2, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
tzoff = SSTOVC(ssp)->vc_sopt.sv_tz; tzoff = SSTOVC(ssp)->vc_sopt.sv_tz;
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
@ -556,6 +584,7 @@ smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime,
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
SMBSDEBUG("%d\n", error); SMBSDEBUG("%d\n", error);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -611,7 +640,7 @@ smbfs_smb_setfattrNT(struct smbnode *np, u_int16_t attr, struct timespec *mtime,
int int
smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred) smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
struct mdchain *mdp; struct mdchain *mdp;
@ -619,9 +648,12 @@ smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred)
u_int16_t fid, wattr, grantedmode; u_int16_t fid, wattr, grantedmode;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_uint16le(mbp, accmode); mb_put_uint16le(mbp, accmode);
@ -652,6 +684,7 @@ smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred)
*/ */
} while(0); } while(0);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
if (error) if (error)
return error; return error;
np->n_fid = fid; np->n_fid = fid;
@ -664,14 +697,17 @@ int
smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime, smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime,
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct mbchain *mbp; struct mbchain *mbp;
u_long time; u_long time;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_mem(mbp, (caddr_t)&fid, sizeof(fid), MB_MSYSTEM); mb_put_mem(mbp, (caddr_t)&fid, sizeof(fid), MB_MSYSTEM);
@ -685,6 +721,7 @@ smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime,
smb_rq_bend(rqp); smb_rq_bend(rqp);
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -692,7 +729,7 @@ int
smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen, smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = dnp->n_mount->sm_share; struct smb_share *ssp = dnp->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
struct mdchain *mdp; struct mdchain *mdp;
@ -702,9 +739,12 @@ smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
u_long tm; u_long tm;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_uint16le(mbp, SMB_FA_ARCHIVE); /* attributes */ mb_put_uint16le(mbp, SMB_FA_ARCHIVE); /* attributes */
@ -731,20 +771,24 @@ smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen,
if (error) if (error)
return error; return error;
smbfs_smb_close(ssp, fid, &ctime, scred); smbfs_smb_close(ssp, fid, &ctime, scred);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
int int
smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred) smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN); mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
@ -757,6 +801,7 @@ smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred)
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
} }
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -764,14 +809,17 @@ int
smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp, smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp,
const char *tname, int tnmlen, struct smb_cred *scred) const char *tname, int tnmlen, struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = src->n_mount->sm_share; struct smb_share *ssp = src->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_RENAME, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_RENAME, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN); mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN);
@ -790,6 +838,7 @@ smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp,
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
} while(0); } while(0);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -797,14 +846,17 @@ int
smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp, smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp,
const char *tname, int tnmlen, u_int16_t flags, struct smb_cred *scred) const char *tname, int tnmlen, u_int16_t flags, struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = src->n_mount->sm_share; struct smb_share *ssp = src->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_MOVE, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_MOVE, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_uint16le(mbp, SMB_TID_UNKNOWN); mb_put_uint16le(mbp, SMB_TID_UNKNOWN);
@ -825,6 +877,7 @@ smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp,
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
} while(0); } while(0);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -832,14 +885,17 @@ int
smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len, smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len,
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = dnp->n_mount->sm_share; struct smb_share *ssp = dnp->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE_DIRECTORY, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE_DIRECTORY, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
smb_rq_wend(rqp); smb_rq_wend(rqp);
@ -851,20 +907,24 @@ smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len,
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
} }
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
int int
smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred) smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE_DIRECTORY, scred); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE_DIRECTORY, scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
smb_rq_wend(rqp); smb_rq_wend(rqp);
@ -876,6 +936,7 @@ smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred)
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
} }
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }
@ -1139,13 +1200,16 @@ smbfs_smb_trans2find2(struct smbfs_fctx *ctx)
static int static int
smbfs_smb_findclose2(struct smbfs_fctx *ctx) smbfs_smb_findclose2(struct smbfs_fctx *ctx)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct mbchain *mbp; struct mbchain *mbp;
int error; int error;
rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ctx->f_ssp), SMB_COM_FIND_CLOSE2, ctx->f_scred); error = smb_rq_init(rqp, SSTOCP(ctx->f_ssp), SMB_COM_FIND_CLOSE2, ctx->f_scred);
if (error) if (error) {
free(rqp, M_SMBFSDATA);
return error; return error;
}
smb_rq_getrequest(rqp, &mbp); smb_rq_getrequest(rqp, &mbp);
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
mb_put_mem(mbp, (caddr_t)&ctx->f_Sid, 2, MB_MSYSTEM); mb_put_mem(mbp, (caddr_t)&ctx->f_Sid, 2, MB_MSYSTEM);
@ -1154,6 +1218,7 @@ smbfs_smb_findclose2(struct smbfs_fctx *ctx)
smb_rq_bend(rqp); smb_rq_bend(rqp);
error = smb_rq_simple(rqp); error = smb_rq_simple(rqp);
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBFSDATA);
return error; return error;
} }

View file

@ -46,6 +46,7 @@
#include <fs/smbfs/smbfs_subr.h> #include <fs/smbfs/smbfs_subr.h>
MALLOC_DEFINE(M_SMBFSDATA, "smbfs_data", "SMBFS private data"); MALLOC_DEFINE(M_SMBFSDATA, "smbfs_data", "SMBFS private data");
MALLOC_DEFINE(M_SMBFSCRED, "smbfs_cred", "SMBFS cred data");
void void
smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds) smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds)
@ -222,3 +223,15 @@ smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int *nmlen, int caseopt)
} }
return error; return error;
} }
void *
smbfs_malloc_scred(void)
{
return (malloc(sizeof(struct smb_cred), M_SMBFSCRED, M_WAITOK));
}
void
smbfs_free_scred(void *scred)
{
free(scred, M_SMBFSCRED);
}

View file

@ -30,6 +30,7 @@
#ifdef MALLOC_DECLARE #ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_SMBFSDATA); MALLOC_DECLARE(M_SMBFSDATA);
MALLOC_DECLARE(M_SMBFSCRED);
#endif #endif
#define SMBFSERR(format, args...) printf("%s: "format, __func__ ,## args) #define SMBFSERR(format, args...) printf("%s: "format, __func__ ,## args)
@ -178,4 +179,6 @@ void smb_time_unix2dos(struct timespec *tsp, int tzoff, u_int16_t *ddp,
u_int16_t *dtp, u_int8_t *dhp); u_int16_t *dtp, u_int8_t *dhp);
void smb_dos2unixtime (u_int dd, u_int dt, u_int dh, int tzoff, struct timespec *tsp); void smb_dos2unixtime (u_int dd, u_int dt, u_int dh, int tzoff, struct timespec *tsp);
void *smbfs_malloc_scred(void);
void smbfs_free_scred(void *);
#endif /* !_FS_SMBFS_SMBFS_SUBR_H_ */ #endif /* !_FS_SMBFS_SMBFS_SUBR_H_ */

View file

@ -137,7 +137,7 @@ smbfs_mount(struct mount *mp)
struct smb_share *ssp = NULL; struct smb_share *ssp = NULL;
struct vnode *vp; struct vnode *vp;
struct thread *td; struct thread *td;
struct smb_cred scred; struct smb_cred *scred;
int error, v; int error, v;
char *pc, *pe; char *pc, *pe;
@ -150,15 +150,18 @@ smbfs_mount(struct mount *mp)
return (EINVAL); return (EINVAL);
} }
smb_makescred(&scred, td, td->td_ucred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, td->td_ucred);
if (1 != vfs_scanopt(mp->mnt_optnew, "dev", "%d", &v)) { if (1 != vfs_scanopt(mp->mnt_optnew, "dev", "%d", &v)) {
vfs_mount_error(mp, "No dev option"); vfs_mount_error(mp, "No dev option");
smbfs_free_scred(scred);
return (EINVAL); return (EINVAL);
} }
error = smb_dev2share(v, SMBM_EXEC, &scred, &ssp); error = smb_dev2share(v, SMBM_EXEC, scred, &ssp);
if (error) { if (error) {
printf("invalid device handle %d (%d)\n", v, error); printf("invalid device handle %d (%d)\n", v, error);
vfs_mount_error(mp, "invalid device handle %d (%d)\n", v, error); vfs_mount_error(mp, "invalid device handle %d (%d)\n", v, error);
smbfs_free_scred(scred);
return error; return error;
} }
vcp = SSTOVC(ssp); vcp = SSTOVC(ssp);
@ -237,6 +240,7 @@ smbfs_mount(struct mount *mp)
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
SMBERROR("mp=%p\n", mp); SMBERROR("mp=%p\n", mp);
#endif #endif
smbfs_free_scred(scred);
return error; return error;
bad: bad:
if (smp) { if (smp) {
@ -246,7 +250,8 @@ smbfs_mount(struct mount *mp)
free(smp, M_SMBFSDATA); free(smp, M_SMBFSDATA);
} }
if (ssp) if (ssp)
smb_share_put(ssp, &scred); smb_share_put(ssp, scred);
smbfs_free_scred(scred);
return error; return error;
} }
@ -256,7 +261,7 @@ smbfs_unmount(struct mount *mp, int mntflags)
{ {
struct thread *td; struct thread *td;
struct smbmount *smp = VFSTOSMBFS(mp); struct smbmount *smp = VFSTOSMBFS(mp);
struct smb_cred scred; struct smb_cred *scred;
int error, flags; int error, flags;
SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags); SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
@ -279,11 +284,12 @@ smbfs_unmount(struct mount *mp, int mntflags)
} while (error == EBUSY && smp->sm_didrele != 0); } while (error == EBUSY && smp->sm_didrele != 0);
if (error) if (error)
return error; return error;
smb_makescred(&scred, td, td->td_ucred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, td->td_ucred);
error = smb_share_lock(smp->sm_share, LK_EXCLUSIVE); error = smb_share_lock(smp->sm_share, LK_EXCLUSIVE);
if (error) if (error)
return error; goto out;
smb_share_put(smp->sm_share, &scred); smb_share_put(smp->sm_share, scred);
mp->mnt_data = NULL; mp->mnt_data = NULL;
if (smp->sm_hash) if (smp->sm_hash)
@ -293,6 +299,8 @@ smbfs_unmount(struct mount *mp, int mntflags)
MNT_ILOCK(mp); MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL; mp->mnt_flag &= ~MNT_LOCAL;
MNT_IUNLOCK(mp); MNT_IUNLOCK(mp);
out:
smbfs_free_scred(scred);
return error; return error;
} }
@ -308,7 +316,7 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp)
struct smbfattr fattr; struct smbfattr fattr;
struct thread *td; struct thread *td;
struct ucred *cred; struct ucred *cred;
struct smb_cred scred; struct smb_cred *scred;
int error; int error;
td = curthread; td = curthread;
@ -323,19 +331,22 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp)
*vpp = SMBTOV(smp->sm_root); *vpp = SMBTOV(smp->sm_root);
return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td); return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td);
} }
smb_makescred(&scred, td, cred); scred = smbfs_malloc_scred();
error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, &scred); smb_makescred(scred, td, cred);
error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, scred);
if (error) if (error)
return error; goto out;
error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp); error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp);
if (error) if (error)
return error; goto out;
ASSERT_VOP_LOCKED(vp, "smbfs_root"); ASSERT_VOP_LOCKED(vp, "smbfs_root");
vp->v_vflag |= VV_ROOT; vp->v_vflag |= VV_ROOT;
np = VTOSMB(vp); np = VTOSMB(vp);
smp->sm_root = np; smp->sm_root = np;
*vpp = vp; *vpp = vp;
return 0; out:
smbfs_free_scred(scred);
return error;
} }
/* /*
@ -381,7 +392,7 @@ smbfs_statfs(struct mount *mp, struct statfs *sbp)
struct smbmount *smp = VFSTOSMBFS(mp); struct smbmount *smp = VFSTOSMBFS(mp);
struct smbnode *np = smp->sm_root; struct smbnode *np = smp->sm_root;
struct smb_share *ssp = smp->sm_share; struct smb_share *ssp = smp->sm_share;
struct smb_cred scred; struct smb_cred *scred;
int error = 0; int error = 0;
if (np == NULL) { if (np == NULL) {
@ -390,14 +401,18 @@ smbfs_statfs(struct mount *mp, struct statfs *sbp)
} }
sbp->f_iosize = SSTOVC(ssp)->vc_txmax; /* optimal transfer block size */ sbp->f_iosize = SSTOVC(ssp)->vc_txmax; /* optimal transfer block size */
smb_makescred(&scred, td, td->td_ucred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, td->td_ucred);
if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0) if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0)
error = smbfs_smb_statfs2(ssp, sbp, &scred); error = smbfs_smb_statfs2(ssp, sbp, scred);
else else
error = smbfs_smb_statfs(ssp, sbp, &scred); error = smbfs_smb_statfs(ssp, sbp, scred);
if (error) if (error) {
smbfs_free_scred(scred);
return error; return error;
}
sbp->f_flags = 0; /* copy of mount exported flags */ sbp->f_flags = 0; /* copy of mount exported flags */
smbfs_free_scred(scred);
return 0; return 0;
} }

View file

@ -153,7 +153,7 @@ smbfs_open(ap)
{ {
struct vnode *vp = ap->a_vp; struct vnode *vp = ap->a_vp;
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct smb_cred scred; struct smb_cred *scred;
struct vattr vattr; struct vattr vattr;
int mode = ap->a_mode; int mode = ap->a_mode;
int error, accmode; int error, accmode;
@ -197,14 +197,15 @@ smbfs_open(ap)
accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD; accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW; accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW;
smb_makescred(&scred, ap->a_td, ap->a_cred); scred = smbfs_malloc_scred();
error = smbfs_smb_open(np, accmode, &scred); smb_makescred(scred, ap->a_td, ap->a_cred);
error = smbfs_smb_open(np, accmode, scred);
if (error) { if (error) {
if (mode & FWRITE) if (mode & FWRITE)
return EACCES; return EACCES;
else if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { else if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD; accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
error = smbfs_smb_open(np, accmode, &scred); error = smbfs_smb_open(np, accmode, scred);
} }
} }
if (error == 0) { if (error == 0) {
@ -212,6 +213,7 @@ smbfs_open(ap)
vnode_create_vobject(ap->a_vp, vattr.va_size, ap->a_td); vnode_create_vobject(ap->a_vp, vattr.va_size, ap->a_td);
} }
smbfs_attr_cacheremove(vp); smbfs_attr_cacheremove(vp);
smbfs_free_scred(scred);
return error; return error;
} }
@ -228,12 +230,14 @@ smbfs_close(ap)
struct vnode *vp = ap->a_vp; struct vnode *vp = ap->a_vp;
struct thread *td = ap->a_td; struct thread *td = ap->a_td;
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct smb_cred scred; struct smb_cred *scred;
if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 && if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 &&
np->n_dirseq != NULL) { np->n_dirseq != NULL) {
smb_makescred(&scred, td, ap->a_cred); scred = smbfs_malloc_scred();
smbfs_findclose(np->n_dirseq, &scred); smb_makescred(scred, td, ap->a_cred);
smbfs_findclose(np->n_dirseq, scred);
smbfs_free_scred(scred);
np->n_dirseq = NULL; np->n_dirseq = NULL;
} }
return 0; return 0;
@ -254,7 +258,7 @@ smbfs_getattr(ap)
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct vattr *va=ap->a_vap; struct vattr *va=ap->a_vap;
struct smbfattr fattr; struct smbfattr fattr;
struct smb_cred scred; struct smb_cred *scred;
u_quad_t oldsize; u_quad_t oldsize;
int error; int error;
@ -263,17 +267,20 @@ smbfs_getattr(ap)
if (!error) if (!error)
return 0; return 0;
SMBVDEBUG("not in the cache\n"); SMBVDEBUG("not in the cache\n");
smb_makescred(&scred, curthread, ap->a_cred); scred = smbfs_malloc_scred();
smb_makescred(scred, curthread, ap->a_cred);
oldsize = np->n_size; oldsize = np->n_size;
error = smbfs_smb_lookup(np, NULL, 0, &fattr, &scred); error = smbfs_smb_lookup(np, NULL, 0, &fattr, scred);
if (error) { if (error) {
SMBVDEBUG("error %d\n", error); SMBVDEBUG("error %d\n", error);
smbfs_free_scred(scred);
return error; return error;
} }
smbfs_attr_cacheenter(vp, &fattr); smbfs_attr_cacheenter(vp, &fattr);
smbfs_attr_cachelookup(vp, va); smbfs_attr_cachelookup(vp, va);
if (np->n_flag & NOPEN) if (np->n_flag & NOPEN)
np->n_size = oldsize; np->n_size = oldsize;
smbfs_free_scred(scred);
return 0; return 0;
} }
@ -289,7 +296,7 @@ smbfs_setattr(ap)
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct vattr *vap = ap->a_vap; struct vattr *vap = ap->a_vap;
struct timespec *mtime, *atime; struct timespec *mtime, *atime;
struct smb_cred scred; struct smb_cred *scred;
struct smb_share *ssp = np->n_mount->sm_share; struct smb_share *ssp = np->n_mount->sm_share;
struct smb_vc *vcp = SSTOVC(ssp); struct smb_vc *vcp = SSTOVC(ssp);
struct thread *td = curthread; struct thread *td = curthread;
@ -308,18 +315,23 @@ smbfs_setattr(ap)
vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
vap->va_mode != (mode_t)VNOVAL) && isreadonly) vap->va_mode != (mode_t)VNOVAL) && isreadonly)
return EROFS; return EROFS;
smb_makescred(&scred, td, ap->a_cred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, ap->a_cred);
if (vap->va_size != VNOVAL) { if (vap->va_size != VNOVAL) {
switch (vp->v_type) { switch (vp->v_type) {
case VDIR: case VDIR:
return EISDIR; error = EISDIR;
goto out;
case VREG: case VREG:
break; break;
default: default:
return EINVAL; error = EINVAL;
goto out;
}; };
if (isreadonly) if (isreadonly) {
return EROFS; error = EROFS;
goto out;
}
doclose = 0; doclose = 0;
vnode_pager_setsize(vp, (u_long)vap->va_size); vnode_pager_setsize(vp, (u_long)vap->va_size);
tsize = np->n_size; tsize = np->n_size;
@ -327,18 +339,18 @@ smbfs_setattr(ap)
if ((np->n_flag & NOPEN) == 0) { if ((np->n_flag & NOPEN) == 0) {
error = smbfs_smb_open(np, error = smbfs_smb_open(np,
SMB_SM_DENYNONE|SMB_AM_OPENRW, SMB_SM_DENYNONE|SMB_AM_OPENRW,
&scred); scred);
if (error == 0) if (error == 0)
doclose = 1; doclose = 1;
} }
if (error == 0) if (error == 0)
error = smbfs_smb_setfsize(np, vap->va_size, &scred); error = smbfs_smb_setfsize(np, vap->va_size, scred);
if (doclose) if (doclose)
smbfs_smb_close(ssp, np->n_fid, NULL, &scred); smbfs_smb_close(ssp, np->n_fid, NULL, scred);
if (error) { if (error) {
np->n_size = tsize; np->n_size = tsize;
vnode_pager_setsize(vp, (u_long)tsize); vnode_pager_setsize(vp, (u_long)tsize);
return error; goto out;
} }
} }
if (vap->va_mode != (mode_t)VNOVAL) { if (vap->va_mode != (mode_t)VNOVAL) {
@ -348,9 +360,9 @@ smbfs_setattr(ap)
else else
np->n_dosattr |= SMB_FA_RDONLY; np->n_dosattr |= SMB_FA_RDONLY;
if (np->n_dosattr != old_n_dosattr) { if (np->n_dosattr != old_n_dosattr) {
error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, &scred); error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, scred);
if (error) if (error)
return error; goto out;
} }
} }
mtime = atime = NULL; mtime = atime = NULL;
@ -381,25 +393,25 @@ smbfs_setattr(ap)
NULL); NULL);
if (!error) { if (!error) {
/* error = smbfs_smb_setfattrNT(np, 0, /* error = smbfs_smb_setfattrNT(np, 0,
mtime, atime, &scred); mtime, atime, scred);
VOP_GETATTR(vp, &vattr, ap->a_cred); */ VOP_GETATTR(vp, &vattr, ap->a_cred); */
if (mtime) if (mtime)
np->n_mtime = *mtime; np->n_mtime = *mtime;
VOP_CLOSE(vp, FWRITE, ap->a_cred, td); VOP_CLOSE(vp, FWRITE, ap->a_cred, td);
} }
} else if ((vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS)) { } else if ((vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS)) {
error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred); error = smbfs_smb_setptime2(np, mtime, atime, 0, scred);
/* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, &scred);*/ /* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, scred);*/
} else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) { } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) {
error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred); error = smbfs_smb_setptime2(np, mtime, atime, 0, scred);
} else { } else {
error = smbfs_smb_setpattr(np, 0, mtime, &scred); error = smbfs_smb_setpattr(np, 0, mtime, scred);
} }
} else { } else {
if (vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS) { if (vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS) {
error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred); error = smbfs_smb_setfattrNT(np, 0, mtime, atime, scred);
} else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) { } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) {
error = smbfs_smb_setftime(np, mtime, atime, &scred); error = smbfs_smb_setftime(np, mtime, atime, scred);
} else { } else {
/* /*
* I have no idea how to handle this for core * I have no idea how to handle this for core
@ -417,6 +429,8 @@ smbfs_setattr(ap)
smbfs_attr_cacheremove(vp); /* invalidate cache */ smbfs_attr_cacheremove(vp); /* invalidate cache */
VOP_GETATTR(vp, vap, ap->a_cred); VOP_GETATTR(vp, vap, ap->a_cred);
np->n_mtime.tv_sec = vap->va_mtime.tv_sec; np->n_mtime.tv_sec = vap->va_mtime.tv_sec;
out:
smbfs_free_scred(scred);
return error; return error;
} }
/* /*
@ -482,7 +496,7 @@ smbfs_create(ap)
struct vnode *vp; struct vnode *vp;
struct vattr vattr; struct vattr vattr;
struct smbfattr fattr; struct smbfattr fattr;
struct smb_cred scred; struct smb_cred *scred;
char *name = cnp->cn_nameptr; char *name = cnp->cn_nameptr;
int nmlen = cnp->cn_namelen; int nmlen = cnp->cn_namelen;
int error; int error;
@ -494,20 +508,23 @@ smbfs_create(ap)
return EOPNOTSUPP; return EOPNOTSUPP;
if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred))) if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)))
return error; return error;
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); scred = smbfs_malloc_scred();
smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
error = smbfs_smb_create(dnp, name, nmlen, &scred); error = smbfs_smb_create(dnp, name, nmlen, scred);
if (error) if (error)
return error; goto out;
error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred); error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, scred);
if (error) if (error)
return error; goto out;
error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, &vp); error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, &vp);
if (error) if (error)
return error; goto out;
*vpp = vp; *vpp = vp;
if (cnp->cn_flags & MAKEENTRY) if (cnp->cn_flags & MAKEENTRY)
cache_enter(dvp, vp, cnp); cache_enter(dvp, vp, cnp);
out:
smbfs_free_scred(scred);
return error; return error;
} }
@ -524,16 +541,18 @@ smbfs_remove(ap)
/* struct vnode *dvp = ap->a_dvp;*/ /* struct vnode *dvp = ap->a_dvp;*/
struct componentname *cnp = ap->a_cnp; struct componentname *cnp = ap->a_cnp;
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct smb_cred scred; struct smb_cred *scred;
int error; int error;
if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 || vrefcnt(vp) != 1) if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 || vrefcnt(vp) != 1)
return EPERM; return EPERM;
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); scred = smbfs_malloc_scred();
error = smbfs_smb_delete(np, &scred); smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
error = smbfs_smb_delete(np, scred);
if (error == 0) if (error == 0)
np->n_flag |= NGONE; np->n_flag |= NGONE;
cache_purge(vp); cache_purge(vp);
smbfs_free_scred(scred);
return error; return error;
} }
@ -557,19 +576,19 @@ smbfs_rename(ap)
struct vnode *tdvp = ap->a_tdvp; struct vnode *tdvp = ap->a_tdvp;
struct componentname *tcnp = ap->a_tcnp; struct componentname *tcnp = ap->a_tcnp;
/* struct componentname *fcnp = ap->a_fcnp;*/ /* struct componentname *fcnp = ap->a_fcnp;*/
struct smb_cred scred; struct smb_cred *scred;
u_int16_t flags = 6; u_int16_t flags = 6;
int error=0; int error=0;
/* Check for cross-device rename */ /* Check for cross-device rename */
if ((fvp->v_mount != tdvp->v_mount) || if ((fvp->v_mount != tdvp->v_mount) ||
(tvp && (fvp->v_mount != tvp->v_mount))) { (tvp && (fvp->v_mount != tvp->v_mount))) {
error = EXDEV; return EXDEV;
goto out; goto out;
} }
if (tvp && vrefcnt(tvp) > 1) { if (tvp && vrefcnt(tvp) > 1) {
error = EBUSY; return EBUSY;
goto out; goto out;
} }
flags = 0x10; /* verify all writes */ flags = 0x10; /* verify all writes */
@ -578,17 +597,17 @@ smbfs_rename(ap)
} else if (fvp->v_type == VREG) { } else if (fvp->v_type == VREG) {
flags |= 1; flags |= 1;
} else { } else {
error = EINVAL; return EINVAL;
goto out;
} }
smb_makescred(&scred, tcnp->cn_thread, tcnp->cn_cred); scred = smbfs_malloc_scred();
smb_makescred(scred, tcnp->cn_thread, tcnp->cn_cred);
/* /*
* It seems that Samba doesn't implement SMB_COM_MOVE call... * It seems that Samba doesn't implement SMB_COM_MOVE call...
*/ */
#ifdef notnow #ifdef notnow
if (SMB_DIALECT(SSTOCN(smp->sm_share)) >= SMB_DIALECT_LANMAN1_0) { if (SMB_DIALECT(SSTOCN(smp->sm_share)) >= SMB_DIALECT_LANMAN1_0) {
error = smbfs_smb_move(VTOSMB(fvp), VTOSMB(tdvp), error = smbfs_smb_move(VTOSMB(fvp), VTOSMB(tdvp),
tcnp->cn_nameptr, tcnp->cn_namelen, flags, &scred); tcnp->cn_nameptr, tcnp->cn_namelen, flags, scred);
} else } else
#endif #endif
{ {
@ -596,13 +615,13 @@ smbfs_rename(ap)
* We have to do the work atomicaly * We have to do the work atomicaly
*/ */
if (tvp && tvp != fvp) { if (tvp && tvp != fvp) {
error = smbfs_smb_delete(VTOSMB(tvp), &scred); error = smbfs_smb_delete(VTOSMB(tvp), scred);
if (error) if (error)
goto out_cacherem; goto out_cacherem;
VTOSMB(fvp)->n_flag |= NGONE; VTOSMB(fvp)->n_flag |= NGONE;
} }
error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp), error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp),
tcnp->cn_nameptr, tcnp->cn_namelen, &scred); tcnp->cn_nameptr, tcnp->cn_namelen, scred);
} }
if (fvp->v_type == VDIR) { if (fvp->v_type == VDIR) {
@ -615,6 +634,7 @@ smbfs_rename(ap)
smbfs_attr_cacheremove(fdvp); smbfs_attr_cacheremove(fdvp);
smbfs_attr_cacheremove(tdvp); smbfs_attr_cacheremove(tdvp);
out: out:
smbfs_free_scred(scred);
if (tdvp == tvp) if (tdvp == tvp)
vrele(tdvp); vrele(tdvp);
else else
@ -685,7 +705,7 @@ smbfs_mkdir(ap)
struct componentname *cnp = ap->a_cnp; struct componentname *cnp = ap->a_cnp;
struct smbnode *dnp = VTOSMB(dvp); struct smbnode *dnp = VTOSMB(dvp);
struct vattr vattr; struct vattr vattr;
struct smb_cred scred; struct smb_cred *scred;
struct smbfattr fattr; struct smbfattr fattr;
char *name = cnp->cn_nameptr; char *name = cnp->cn_nameptr;
int len = cnp->cn_namelen; int len = cnp->cn_namelen;
@ -696,17 +716,20 @@ smbfs_mkdir(ap)
} }
if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.')))) if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.'))))
return EEXIST; return EEXIST;
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); scred = smbfs_malloc_scred();
error = smbfs_smb_mkdir(dnp, name, len, &scred); smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
error = smbfs_smb_mkdir(dnp, name, len, scred);
if (error) if (error)
return error; goto out;
error = smbfs_smb_lookup(dnp, name, len, &fattr, &scred); error = smbfs_smb_lookup(dnp, name, len, &fattr, scred);
if (error) if (error)
return error; goto out;
error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp); error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp);
if (error) if (error)
return error; goto out;
*ap->a_vpp = vp; *ap->a_vpp = vp;
out:
smbfs_free_scred(scred);
return 0; return 0;
} }
@ -727,20 +750,22 @@ smbfs_rmdir(ap)
/* struct smbmount *smp = VTOSMBFS(vp);*/ /* struct smbmount *smp = VTOSMBFS(vp);*/
struct smbnode *dnp = VTOSMB(dvp); struct smbnode *dnp = VTOSMB(dvp);
struct smbnode *np = VTOSMB(vp); struct smbnode *np = VTOSMB(vp);
struct smb_cred scred; struct smb_cred *scred;
int error; int error;
if (dvp == vp) if (dvp == vp)
return EINVAL; return EINVAL;
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); scred = smbfs_malloc_scred();
error = smbfs_smb_rmdir(np, &scred); smb_makescred(scred, cnp->cn_thread, cnp->cn_cred);
error = smbfs_smb_rmdir(np, scred);
if (error == 0) if (error == 0)
np->n_flag |= NGONE; np->n_flag |= NGONE;
dnp->n_flag |= NMODIFIED; dnp->n_flag |= NMODIFIED;
smbfs_attr_cacheremove(dvp); smbfs_attr_cacheremove(dvp);
/* cache_purge(dvp);*/ /* cache_purge(dvp);*/
cache_purge(vp); cache_purge(vp);
smbfs_free_scred(scred);
return error; return error;
} }
@ -936,7 +961,7 @@ smbfs_advlock(ap)
caddr_t id = (caddr_t)1 /* ap->a_id */; caddr_t id = (caddr_t)1 /* ap->a_id */;
/* int flags = ap->a_flags;*/ /* int flags = ap->a_flags;*/
struct thread *td = curthread; struct thread *td = curthread;
struct smb_cred scred; struct smb_cred *scred;
u_quad_t size; u_quad_t size;
off_t start, end, oadd; off_t start, end, oadd;
int error, lkop; int error, lkop;
@ -986,7 +1011,8 @@ smbfs_advlock(ap)
return EOVERFLOW; return EOVERFLOW;
end = start + oadd; end = start + oadd;
} }
smb_makescred(&scred, td, td->td_ucred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, td->td_ucred);
switch (ap->a_op) { switch (ap->a_op) {
case F_SETLK: case F_SETLK:
switch (fl->l_type) { switch (fl->l_type) {
@ -1000,13 +1026,14 @@ smbfs_advlock(ap)
lkop = SMB_LOCK_RELEASE; lkop = SMB_LOCK_RELEASE;
break; break;
default: default:
smbfs_free_scred(scred);
return EINVAL; return EINVAL;
} }
error = lf_advlock(ap, &vp->v_lockf, size); error = lf_advlock(ap, &vp->v_lockf, size);
if (error) if (error)
break; break;
lkop = SMB_LOCK_EXCL; lkop = SMB_LOCK_EXCL;
error = smbfs_smb_lock(np, lkop, id, start, end, &scred); error = smbfs_smb_lock(np, lkop, id, start, end, scred);
if (error) { if (error) {
int oldtype = fl->l_type; int oldtype = fl->l_type;
fl->l_type = F_UNLCK; fl->l_type = F_UNLCK;
@ -1017,14 +1044,16 @@ smbfs_advlock(ap)
break; break;
case F_UNLCK: case F_UNLCK:
lf_advlock(ap, &vp->v_lockf, size); lf_advlock(ap, &vp->v_lockf, size);
error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, id, start, end, &scred); error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, id, start, end, scred);
break; break;
case F_GETLK: case F_GETLK:
error = lf_advlock(ap, &vp->v_lockf, size); error = lf_advlock(ap, &vp->v_lockf, size);
break; break;
default: default:
smbfs_free_scred(scred);
return EINVAL; return EINVAL;
} }
smbfs_free_scred(scred);
return error; return error;
} }
@ -1091,7 +1120,7 @@ smbfs_lookup(ap)
struct mount *mp = dvp->v_mount; struct mount *mp = dvp->v_mount;
struct smbnode *dnp; struct smbnode *dnp;
struct smbfattr fattr, *fap; struct smbfattr fattr, *fap;
struct smb_cred scred; struct smb_cred *scred;
char *name = cnp->cn_nameptr; char *name = cnp->cn_nameptr;
int flags = cnp->cn_flags; int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop; int nameiop = cnp->cn_nameiop;
@ -1182,20 +1211,21 @@ smbfs_lookup(ap)
*/ */
error = 0; error = 0;
*vpp = NULLVP; *vpp = NULLVP;
smb_makescred(&scred, td, cnp->cn_cred); scred = smbfs_malloc_scred();
smb_makescred(scred, td, cnp->cn_cred);
fap = &fattr; fap = &fattr;
if (flags & ISDOTDOT) { if (flags & ISDOTDOT) {
error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap, error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
&scred); scred);
SMBVDEBUG("result of dotdot lookup: %d\n", error); SMBVDEBUG("result of dotdot lookup: %d\n", error);
} else { } else {
fap = &fattr; fap = &fattr;
error = smbfs_smb_lookup(dnp, name, nmlen, fap, &scred); error = smbfs_smb_lookup(dnp, name, nmlen, fap, scred);
/* if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')*/ /* if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')*/
SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error); SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error);
} }
if (error && error != ENOENT) if (error && error != ENOENT)
return error; goto out;
if (error) { /* entry not found */ if (error) { /* entry not found */
/* /*
* Handle RENAME or CREATE case... * Handle RENAME or CREATE case...
@ -1203,11 +1233,13 @@ smbfs_lookup(ap)
if ((nameiop == CREATE || nameiop == RENAME) && islastcn) { if ((nameiop == CREATE || nameiop == RENAME) && islastcn) {
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
if (error) if (error)
return error; goto out;
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
return (EJUSTRETURN); error = EJUSTRETURN;
goto out;
} }
return ENOENT; error = ENOENT;
goto out;
}/* else { }/* else {
SMBVDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum); SMBVDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum);
}*/ }*/
@ -1217,38 +1249,40 @@ smbfs_lookup(ap)
if (nameiop == DELETE && islastcn) { /* delete last component */ if (nameiop == DELETE && islastcn) { /* delete last component */
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
if (error) if (error)
return error; goto out;
if (isdot) { if (isdot) {
VREF(dvp); VREF(dvp);
*vpp = dvp; *vpp = dvp;
return 0; goto out;
} }
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp); error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
if (error) if (error)
return error; goto out;
*vpp = vp; *vpp = vp;
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
return 0; goto out;
} }
if (nameiop == RENAME && islastcn) { if (nameiop == RENAME && islastcn) {
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
if (error) if (error)
return error; goto out;
if (isdot) if (isdot) {
return EISDIR; error = EISDIR;
goto out;
}
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp); error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
if (error) if (error)
return error; goto out;
*vpp = vp; *vpp = vp;
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
return 0; goto out;
} }
if (flags & ISDOTDOT) { if (flags & ISDOTDOT) {
VOP_UNLOCK(dvp, 0); VOP_UNLOCK(dvp, 0);
error = smbfs_nget(mp, dvp, name, nmlen, NULL, &vp); error = smbfs_nget(mp, dvp, name, nmlen, NULL, &vp);
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
if (error) if (error)
return error; goto out;
*vpp = vp; *vpp = vp;
} else if (isdot) { } else if (isdot) {
vref(dvp); vref(dvp);
@ -1256,7 +1290,7 @@ smbfs_lookup(ap)
} else { } else {
error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp); error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
if (error) if (error)
return error; goto out;
*vpp = vp; *vpp = vp;
SMBVDEBUG("lookup: getnewvp!\n"); SMBVDEBUG("lookup: getnewvp!\n");
} }
@ -1264,5 +1298,7 @@ smbfs_lookup(ap)
/* VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_vattr.va_ctime.tv_sec;*/ /* VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_vattr.va_ctime.tv_sec;*/
cache_enter(dvp, *vpp, cnp); cache_enter(dvp, *vpp, cnp);
} }
return 0; out:
smbfs_free_scred(scred);
return (error);
} }

View file

@ -868,8 +868,6 @@ smb_share_getinfo(struct smb_share *ssp, struct smb_share_info *sip)
static int static int
smb_sysctl_treedump(SYSCTL_HANDLER_ARGS) smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
{ {
struct thread *td = req->td;
struct smb_cred scred;
struct smb_connobj *scp1, *scp2; struct smb_connobj *scp1, *scp2;
struct smb_vc *vcp; struct smb_vc *vcp;
struct smb_share *ssp; struct smb_share *ssp;
@ -877,7 +875,6 @@ smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
struct smb_share_info ssi; struct smb_share_info ssi;
int error, itype; int error, itype;
smb_makescred(&scred, td, td->td_ucred);
error = sysctl_wire_old_buffer(req, 0); error = sysctl_wire_old_buffer(req, 0);
if (error) if (error)
return (error); return (error);

View file

@ -157,22 +157,24 @@ nsmb_dev_close(struct cdev *dev, int flag, int fmt, struct thread *td)
struct smb_dev *sdp; struct smb_dev *sdp;
struct smb_vc *vcp; struct smb_vc *vcp;
struct smb_share *ssp; struct smb_share *ssp;
struct smb_cred scred; struct smb_cred *scred;
int s; int s;
scred = malloc(sizeof(struct smb_cred), M_NSMBDEV, M_WAITOK);
SMB_CHECKMINOR(dev); SMB_CHECKMINOR(dev);
s = splimp(); s = splimp();
if ((sdp->sd_flags & NSMBFL_OPEN) == 0) { if ((sdp->sd_flags & NSMBFL_OPEN) == 0) {
splx(s); splx(s);
free(scred, M_NSMBDEV);
return EBADF; return EBADF;
} }
smb_makescred(&scred, td, NULL); smb_makescred(scred, td, NULL);
ssp = sdp->sd_share; ssp = sdp->sd_share;
if (ssp != NULL) if (ssp != NULL)
smb_share_rele(ssp, &scred); smb_share_rele(ssp, scred);
vcp = sdp->sd_vc; vcp = sdp->sd_vc;
if (vcp != NULL) if (vcp != NULL)
smb_vc_rele(vcp, &scred); smb_vc_rele(vcp, scred);
/* /*
smb_flushq(&sdp->sd_rqlist); smb_flushq(&sdp->sd_rqlist);
smb_flushq(&sdp->sd_rplist); smb_flushq(&sdp->sd_rplist);
@ -181,6 +183,7 @@ nsmb_dev_close(struct cdev *dev, int flag, int fmt, struct thread *td)
free(sdp, M_NSMBDEV); free(sdp, M_NSMBDEV);
destroy_dev_sched(dev); destroy_dev_sched(dev);
splx(s); splx(s);
free(scred, M_NSMBDEV);
return 0; return 0;
} }
@ -191,20 +194,23 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
struct smb_dev *sdp; struct smb_dev *sdp;
struct smb_vc *vcp; struct smb_vc *vcp;
struct smb_share *ssp; struct smb_share *ssp;
struct smb_cred scred; struct smb_cred *scred;
int error = 0; int error = 0;
SMB_CHECKMINOR(dev); SMB_CHECKMINOR(dev);
if ((sdp->sd_flags & NSMBFL_OPEN) == 0) if ((sdp->sd_flags & NSMBFL_OPEN) == 0)
return EBADF; return EBADF;
smb_makescred(&scred, td, NULL); scred = malloc(sizeof(struct smb_cred), M_NSMBDEV, M_WAITOK);
smb_makescred(scred, td, NULL);
switch (cmd) { switch (cmd) {
case SMBIOC_OPENSESSION: case SMBIOC_OPENSESSION:
if (sdp->sd_vc) if (sdp->sd_vc) {
return EISCONN; error = EISCONN;
goto out;
}
error = smb_usr_opensession((struct smbioc_ossn*)data, error = smb_usr_opensession((struct smbioc_ossn*)data,
&scred, &vcp); scred, &vcp);
if (error) if (error)
break; break;
sdp->sd_vc = vcp; sdp->sd_vc = vcp;
@ -212,12 +218,16 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
sdp->sd_level = SMBL_VC; sdp->sd_level = SMBL_VC;
break; break;
case SMBIOC_OPENSHARE: case SMBIOC_OPENSHARE:
if (sdp->sd_share) if (sdp->sd_share) {
return EISCONN; error = EISCONN;
if (sdp->sd_vc == NULL) goto out;
return ENOTCONN; }
if (sdp->sd_vc == NULL) {
error = ENOTCONN;
goto out;
}
error = smb_usr_openshare(sdp->sd_vc, error = smb_usr_openshare(sdp->sd_vc,
(struct smbioc_oshare*)data, &scred, &ssp); (struct smbioc_oshare*)data, scred, &ssp);
if (error) if (error)
break; break;
sdp->sd_share = ssp; sdp->sd_share = ssp;
@ -225,16 +235,20 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
sdp->sd_level = SMBL_SHARE; sdp->sd_level = SMBL_SHARE;
break; break;
case SMBIOC_REQUEST: case SMBIOC_REQUEST:
if (sdp->sd_share == NULL) if (sdp->sd_share == NULL) {
return ENOTCONN; error = ENOTCONN;
goto out;
}
error = smb_usr_simplerequest(sdp->sd_share, error = smb_usr_simplerequest(sdp->sd_share,
(struct smbioc_rq*)data, &scred); (struct smbioc_rq*)data, scred);
break; break;
case SMBIOC_T2RQ: case SMBIOC_T2RQ:
if (sdp->sd_share == NULL) if (sdp->sd_share == NULL) {
return ENOTCONN; error = ENOTCONN;
goto out;
}
error = smb_usr_t2request(sdp->sd_share, error = smb_usr_t2request(sdp->sd_share,
(struct smbioc_t2rq*)data, &scred); (struct smbioc_t2rq*)data, scred);
break; break;
case SMBIOC_SETFLAGS: { case SMBIOC_SETFLAGS: {
struct smbioc_flags *fl = (struct smbioc_flags*)data; struct smbioc_flags *fl = (struct smbioc_flags*)data;
@ -243,9 +257,11 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
if (fl->ioc_level == SMBL_VC) { if (fl->ioc_level == SMBL_VC) {
if (fl->ioc_mask & SMBV_PERMANENT) { if (fl->ioc_mask & SMBV_PERMANENT) {
on = fl->ioc_flags & SMBV_PERMANENT; on = fl->ioc_flags & SMBV_PERMANENT;
if ((vcp = sdp->sd_vc) == NULL) if ((vcp = sdp->sd_vc) == NULL) {
return ENOTCONN; error = ENOTCONN;
error = smb_vc_get(vcp, LK_EXCLUSIVE, &scred); goto out;
}
error = smb_vc_get(vcp, LK_EXCLUSIVE, scred);
if (error) if (error)
break; break;
if (on && (vcp->obj.co_flags & SMBV_PERMANENT) == 0) { if (on && (vcp->obj.co_flags & SMBV_PERMANENT) == 0) {
@ -253,17 +269,19 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
smb_vc_ref(vcp); smb_vc_ref(vcp);
} else if (!on && (vcp->obj.co_flags & SMBV_PERMANENT)) { } else if (!on && (vcp->obj.co_flags & SMBV_PERMANENT)) {
vcp->obj.co_flags &= ~SMBV_PERMANENT; vcp->obj.co_flags &= ~SMBV_PERMANENT;
smb_vc_rele(vcp, &scred); smb_vc_rele(vcp, scred);
} }
smb_vc_put(vcp, &scred); smb_vc_put(vcp, scred);
} else } else
error = EINVAL; error = EINVAL;
} else if (fl->ioc_level == SMBL_SHARE) { } else if (fl->ioc_level == SMBL_SHARE) {
if (fl->ioc_mask & SMBS_PERMANENT) { if (fl->ioc_mask & SMBS_PERMANENT) {
on = fl->ioc_flags & SMBS_PERMANENT; on = fl->ioc_flags & SMBS_PERMANENT;
if ((ssp = sdp->sd_share) == NULL) if ((ssp = sdp->sd_share) == NULL) {
return ENOTCONN; error = ENOTCONN;
error = smb_share_get(ssp, LK_EXCLUSIVE, &scred); goto out;
}
error = smb_share_get(ssp, LK_EXCLUSIVE, scred);
if (error) if (error)
break; break;
if (on && (ssp->obj.co_flags & SMBS_PERMANENT) == 0) { if (on && (ssp->obj.co_flags & SMBS_PERMANENT) == 0) {
@ -271,9 +289,9 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
smb_share_ref(ssp); smb_share_ref(ssp);
} else if (!on && (ssp->obj.co_flags & SMBS_PERMANENT)) { } else if (!on && (ssp->obj.co_flags & SMBS_PERMANENT)) {
ssp->obj.co_flags &= ~SMBS_PERMANENT; ssp->obj.co_flags &= ~SMBS_PERMANENT;
smb_share_rele(ssp, &scred); smb_share_rele(ssp, scred);
} }
smb_share_put(ssp, &scred); smb_share_put(ssp, scred);
} else } else
error = EINVAL; error = EINVAL;
break; break;
@ -282,11 +300,13 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
break; break;
} }
case SMBIOC_LOOKUP: case SMBIOC_LOOKUP:
if (sdp->sd_vc || sdp->sd_share) if (sdp->sd_vc || sdp->sd_share) {
return EISCONN; error = EISCONN;
goto out;
}
vcp = NULL; vcp = NULL;
ssp = NULL; ssp = NULL;
error = smb_usr_lookup((struct smbioc_lookup*)data, &scred, &vcp, &ssp); error = smb_usr_lookup((struct smbioc_lookup*)data, scred, &vcp, &ssp);
if (error) if (error)
break; break;
if (vcp) { if (vcp) {
@ -305,8 +325,10 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
struct uio auio; struct uio auio;
struct iovec iov; struct iovec iov;
if ((ssp = sdp->sd_share) == NULL) if ((ssp = sdp->sd_share) == NULL) {
return ENOTCONN; error = ENOTCONN;
goto out;
}
iov.iov_base = rwrq->ioc_base; iov.iov_base = rwrq->ioc_base;
iov.iov_len = rwrq->ioc_cnt; iov.iov_len = rwrq->ioc_cnt;
auio.uio_iov = &iov; auio.uio_iov = &iov;
@ -317,15 +339,17 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre
auio.uio_rw = (cmd == SMBIOC_READ) ? UIO_READ : UIO_WRITE; auio.uio_rw = (cmd == SMBIOC_READ) ? UIO_READ : UIO_WRITE;
auio.uio_td = td; auio.uio_td = td;
if (cmd == SMBIOC_READ) if (cmd == SMBIOC_READ)
error = smb_read(ssp, rwrq->ioc_fh, &auio, &scred); error = smb_read(ssp, rwrq->ioc_fh, &auio, scred);
else else
error = smb_write(ssp, rwrq->ioc_fh, &auio, &scred); error = smb_write(ssp, rwrq->ioc_fh, &auio, scred);
rwrq->ioc_cnt -= auio.uio_resid; rwrq->ioc_cnt -= auio.uio_resid;
break; break;
} }
default: default:
error = ENODEV; error = ENODEV;
} }
out:
free(scred, M_NSMBDEV);
return error; return error;
} }

View file

@ -192,8 +192,8 @@ nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct thread *td)
static int static int
nbssn_rq_request(struct nbpcb *nbp, struct thread *td) nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
{ {
struct mbchain mb, *mbp = &mb; struct mbchain *mbp;
struct mdchain md, *mdp = &md; struct mdchain *mdp;
struct mbuf *m0; struct mbuf *m0;
struct timeval tv; struct timeval tv;
struct sockaddr_in sin; struct sockaddr_in sin;
@ -201,9 +201,14 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
u_int8_t rpcode; u_int8_t rpcode;
int error, rplen; int error, rplen;
mbp = malloc(sizeof(struct mbchain), M_NBDATA, M_WAITOK);
mdp = malloc(sizeof(struct mbchain), M_NBDATA, M_WAITOK);
error = mb_init(mbp); error = mb_init(mbp);
if (error) if (error) {
free(mbp, M_NBDATA);
free(mdp, M_NBDATA);
return error; return error;
}
mb_put_uint32le(mbp, 0); mb_put_uint32le(mbp, 0);
nb_put_name(mbp, nbp->nbp_paddr); nb_put_name(mbp, nbp->nbp_paddr);
nb_put_name(mbp, nbp->nbp_laddr); nb_put_name(mbp, nbp->nbp_laddr);
@ -214,19 +219,26 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
} }
mb_detach(mbp); mb_detach(mbp);
mb_done(mbp); mb_done(mbp);
if (error) free(mbp, M_NBDATA);
if (error) {
free(mdp, M_NBDATA);
return error; return error;
}
TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo); TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo);
error = selsocket(nbp->nbp_tso, POLLIN, &tv, td); error = selsocket(nbp->nbp_tso, POLLIN, &tv, td);
if (error == EWOULDBLOCK) { /* Timeout */ if (error == EWOULDBLOCK) { /* Timeout */
NBDEBUG("initial request timeout\n"); NBDEBUG("initial request timeout\n");
free(mdp, M_NBDATA);
return ETIMEDOUT; return ETIMEDOUT;
} }
if (error) /* restart or interrupt */ if (error) { /* restart or interrupt */
free(mdp, M_NBDATA);
return error; return error;
}
error = nbssn_recv(nbp, &m0, &rplen, &rpcode, td); error = nbssn_recv(nbp, &m0, &rplen, &rpcode, td);
if (error) { if (error) {
NBDEBUG("recv() error %d\n", error); NBDEBUG("recv() error %d\n", error);
free(mdp, M_NBDATA);
return error; return error;
} }
/* /*
@ -264,6 +276,7 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
} while(0); } while(0);
if (m0) if (m0)
md_done(mdp); md_done(mdp);
free(mdp, M_NBDATA);
return error; return error;
} }

View file

@ -127,8 +127,8 @@ smb_usr_lookup(struct smbioc_lookup *dp, struct smb_cred *scred,
struct smb_vc **vcpp, struct smb_share **sspp) struct smb_vc **vcpp, struct smb_share **sspp)
{ {
struct smb_vc *vcp = NULL; struct smb_vc *vcp = NULL;
struct smb_vcspec vspec; struct smb_vcspec vspec; /* XXX */
struct smb_sharespec sspec, *sspecp = NULL; struct smb_sharespec sspec, *sspecp = NULL; /* XXX */
int error; int error;
if (dp->ioc_level < SMBL_VC || dp->ioc_level > SMBL_SHARE) if (dp->ioc_level < SMBL_VC || dp->ioc_level > SMBL_SHARE)
@ -212,7 +212,7 @@ int
smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp, smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp,
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_rq rq, *rqp = &rq; struct smb_rq *rqp;
struct mbchain *mbp; struct mbchain *mbp;
struct mdchain *mdp; struct mdchain *mdp;
u_int8_t wc; u_int8_t wc;
@ -231,9 +231,12 @@ smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp,
case SMB_COM_TREE_CONNECT_ANDX: case SMB_COM_TREE_CONNECT_ANDX:
return EPERM; return EPERM;
} }
rqp = malloc(sizeof(struct smb_rq), M_SMBTEMP, M_WAITOK);
error = smb_rq_init(rqp, SSTOCP(ssp), dp->ioc_cmd, scred); error = smb_rq_init(rqp, SSTOCP(ssp), dp->ioc_cmd, scred);
if (error) if (error) {
free(rqp, M_SMBTEMP);
return error; return error;
}
mbp = &rqp->sr_rq; mbp = &rqp->sr_rq;
smb_rq_wstart(rqp); smb_rq_wstart(rqp);
error = mb_put_mem(mbp, dp->ioc_twords, dp->ioc_twc * 2, MB_MUSER); error = mb_put_mem(mbp, dp->ioc_twords, dp->ioc_twc * 2, MB_MUSER);
@ -271,6 +274,7 @@ smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp,
dp->ioc_serror = rqp->sr_serror; dp->ioc_serror = rqp->sr_serror;
dp->ioc_error = rqp->sr_error; dp->ioc_error = rqp->sr_error;
smb_rq_done(rqp); smb_rq_done(rqp);
free(rqp, M_SMBTEMP);
return error; return error;
} }
@ -292,15 +296,18 @@ int
smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *dp, smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *dp,
struct smb_cred *scred) struct smb_cred *scred)
{ {
struct smb_t2rq t2, *t2p = &t2; struct smb_t2rq *t2p;
struct mdchain *mdp; struct mdchain *mdp;
int error, len; int error, len;
if (dp->ioc_setupcnt > 3) if (dp->ioc_setupcnt > 3)
return EINVAL; return EINVAL;
t2p = malloc(sizeof(struct smb_t2rq), M_SMBTEMP, M_WAITOK);
error = smb_t2_init(t2p, SSTOCP(ssp), dp->ioc_setup[0], scred); error = smb_t2_init(t2p, SSTOCP(ssp), dp->ioc_setup[0], scred);
if (error) if (error) {
free(t2p, M_SMBTEMP);
return error; return error;
}
len = t2p->t2_setupcount = dp->ioc_setupcnt; len = t2p->t2_setupcount = dp->ioc_setupcnt;
if (len > 1) if (len > 1)
t2p->t2_setupdata = dp->ioc_setup; t2p->t2_setupdata = dp->ioc_setup;
@ -351,5 +358,6 @@ smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *dp,
if (t2p->t_name) if (t2p->t_name)
smb_strfree(t2p->t_name); smb_strfree(t2p->t_name);
smb_t2_done(t2p); smb_t2_done(t2p);
free(t2p, M_SMBTEMP);
return error; return error;
} }